AngularJS笔记

来源:互联网 发布:大学生网络创业计划书 编辑:程序博客网 时间:2024/05/16 06:16
  • 简单页面的 AngularJS 代码结构
  • FAQ
  • API
  • 采用 AngularJS 的 app
  • AngularUI
  • Bootstrap UI
  • AngularJS + Bootstrap 的界面设计参考
  • Cheat Sheet
  • Angular Pickadate
  1. 初始化代码目录 (angular-seed)
  2. 按照设计,先把首页 index.html 完成
  3. 在 app/js/app.js 中规划 routing

使用 resource 而不是使用相对原始的 http

通过实际交互流程来理解

  • 数据录入页
    • directives -> HTML 的扩展语义 (例如, ng-model, ng-controller, 以及自定义的)
    • controller -> application behavior (例如,点击保存按钮对应的操作) 一般用在 div 上,已 assigns behavior to a scope
    • model -> your application data (例如,输入用户名,在 js 代码里处理时,不需要通过 DOM 的方式来获取,直接通过知道的 model 名字获取即可) ngModel is directive that tells Angular to do two-way data binding.
  • 数据展示页
    • service -> 对后端的 RESTful api 进行操作
    • 更底层的采用 $http
    • filter -> 过滤需要展示的数据,也可以自定义 filter
  • module -> configures the injector
  • injector -> assembles your application
  • model -> your application data

angular-seed 默认在 app/js 目录下产生了 5 个 js 文件。

  • app.js
  • controllers.js
  • directives.js
  • filters.js
  • services.js

实际上可以写成一个文件

angular.module('myModule', []).  value('a', 123).  factory('a', function() { return 123; }).  directive('directiveName', ...).  filter('filterName', ...);

分成多个文件的原因

The reason for this breakup is that in your tests, it is often necessary toignore the initialization code, which tends to be difficult to test. Byputting it into a separate module it can be easily ignored in tests. The testscan also be more focused by only loading the modules that are relevant totests.

通过对比这 5 个文件,可以发现

  • 除了 controllers.js 其他 4 个 js 文件都是以 angular.module() 开头
    • directives.js -> angular.module("myApp.directives", []).directive();
    • filters.js -> angular.module("myApp.filters", []).filter();
    • services.js -> angular.module("myApp.services", []).factory();
    • app.js -> angular.module("myApp", ["myApp.filters", "myApp.services", "myApp.directives"]).config();
    • 可见 myApp.filters, myApp.services, myApp.directives 均是自定义的名字, 若写成一个 js 文件,则可以省去这些自定义的名字
  • controllers.js 则是直接 function ControllerName() {}
  • 'use strict'; 每个 AngularJS 文件都采用了 JS 的严格模式
  • ControllerName.$inject = []; 用来注册 controller 的依赖关系。可省略,交由 AngularJS 自动分析。还是推荐写上。
      例如,   function ControllerName($log) {}   ControllerName.$inject = ["$log"] 就是用到了 log service.

可以认为这是一个全局访问的常量, 在 services.js 中定义

angular.module("myApp.services", []).  value("name", "Zhongwei Sun");

在 filters.js 以及 directives.js 中可以看到这样的写法

directive("appVersion", ["version", function(version) {}]);

这是一个 Inline Annotation,因为匿名的回调函数不方便通过设置 $inject 属性的方法来解决依赖,所以采用这样的语法。

再例如,如果要使用 $log

directive("appVersion", ["$log", function($log) {}]);

实际上也可以写成

directive("appVersion", function($log) {});

但是还是推荐写成第一种形式。第一种形式可以称为显式依赖注入,与之对应的就是隐式依赖注入。隐式依赖注入可以引起的问题:

假如我们需要压缩、混淆我们的代码,这可能会导致参数名称被更改,遇到这种情况的时候,我们还是需要使用显式声明依赖的方式。

还有一种是 module 间的依赖,例如, 我要使用 ngResource module 中的 $resource:

<script src="lib/angular/angular-resource.js"></script>ngular.module('phonecatServices', ['ngResource']).    factory('Phone', function($resource){  return $resource('phones/:phoneId.json', {}, {    query: {method:'GET', params:{phoneId:'phones'}, isArray:true}  });});

参考:

  • https://groups.google.com/forum/#!msg/angular/UkXOVU8_3sw/Y3_gxY3DctAJ
  • http://docs.angularjs.org/guide/di
  • http://www.cnblogs.com/lcllao/archive/2012/10/16.html

AngularJS has dependency injection at its core, 小应用不需要考虑加载顺序。

  • js 里定义:directive 在定义的时候采用 ngModel 的形式
  • html 里使用:ng-model

参考:

  • http://blog.jdriven.com/2012/10/adding-custom-html-attributes-to-your-angularjs-web-app/
return $resource("/todos/:todoId", {todoId: "@id"}

这里的 /todos 对应的即是根目录

对于返回的 json 结构中包含错误码的情况,需要将 query 的 isArray 参数设置为fasle. 否则会报上面的错误。然后在 controller 中对结果进行解析。

  • HTTP GET "class" actions: Resource.action([parameters], [success], [error])
  • non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
  • non-GET instance actions: instance.$action([parameters], [success], [error])

save, remove, delete 需要加 $ 前缀,但是只是在实例化的情况下。若是直接使用类的delete 则不需要加此前缀。

代码示例:

  • http://jsfiddle.net/kstep/j25aj/9/
  • http://jsfiddle.net/pjstarifa/uj98n/2/
  • AngularUI 是用 AngularJS 写的一些小功能组件,例如 date picker
  • Bootstrap UI 则是使用 AngularJS 将 Bootstrap 的逻辑重写实现了一遍
<form class="form" novalidate>  <input type="text" required /></form>

首先需要禁用掉浏览器自带的 form 验证,即使用 novalidate. 原因是,不同浏览器的行为有差异。比如,chrome 对标记了 required 的输入框,在输入为空的情况下,自动进行了提示。但是,其他浏览器就没有该行为,比如 safari. 所以需要使用统一的验证方式。

问题,controller 里的逻辑执行了两次。

原因,controller 在 routing 以及 partial html 里定义了两次。

解决方法,去掉 partial 里的 ng-control 定义.

参考:

  • https://groups.google.com/forum/#!topic/angular/yU5cvFKpdE4
  • service 中不要定义 delete 方法, delete 由于是 js 的关键字,会造成 IE 下的不兼容,完全编译不了
    • 需要进行浏览器兼容性测试(手动,自动)
    • 使用 jslint 检测代码问题
    • 做法是不使用 delete, 用 remove 替代
    • https://groups.google.com/forum/?fromgroups=#!topic/angular/W0R6KKfv8QE
  • partial view 中的 google ad 无法显示
    • 放到 index.html 中
    • https://groups.google.com/forum/?fromgroups=#!topic/angular/EyoYWZmsa3o
  • Cross-site request forgery:跨站请求伪造 CSRF
    • http://stackoverflow.com/questions/14109927/angular-js-verify-csrf-token-in-post-request
  • 使用 ng-repeat 做双向绑定时,若结果集是随时更新,最好使用 array, 而不是 map
    • 因为 map 默认不是双向绑定的
  • Javascript Promise 为什么这么迷人
  • Understanding JavaScript Object Creation Patterns

* http://docs.angularjs.org/api/ng.\)http#methods_jsonp

0 0
原创粉丝点击