angularjs里的factory factory中的function变成字符串赋给clusterDataInfo,求解

angularjs 中的$q - 开源中国社区
当前访客身份:游客 [
当前位置:
请教关于angularjs中的$q,
这个作为委托的类,,,具体resolve的作用到底是什么,在如下代码中,deferred.resolve(data); 把传回来的数据放到里面有什么意义呢,我并没有针对deferred.resolve设定什么操作啊,如果在success外面设置一个对象ob来作为闭包传进去,又有什么区别啊?
angular.module('myApp', [])
.factory('GithubService', [
'$q', '$http',
function($q, $http) {
var getPullRequests = function() {
var deferred = $q.defer();
// 从Github获取打开的angularjs pull请求列表
$http.get('/repos/angular/angular.js/pulls')
.success(function(data) {
deferred.resolve(data);
.error(function(reason) {
deferred.reject(reason);
return deferred.
return { // 返回工厂对象
getPullRequests: getPullRequests
共有1个答案
<span class="a_vote_num" id="a_vote_num_
现在懂了,应该~,谢谢大家
更多开发者职位上
有什么技术问题吗?
gogojxj...的其它问题
类似的话题AngularJS中的模块详解
投稿:junjie
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了AngularJS中的模块详解,本文给出了一个模块实例,需要的朋友可以参考下
在讲angularjs的模块之前,我们先介绍一下angular的一些知识点:
AngularJS是纯客户端技术,完全用Javascript编写的。它使用的是网页开发的常规技术(HTML,CSS,Javascript),目的是让网页应用开发更快更容易。
AngularJS简化应用开发的一个重要方法是,将一个些通用的低级开发操作包装起来提供给开发者。AngularJS会自动处理好这些低级操作。它们包括:
2.设置事件的监听
3.输入验证,因为AngularJS会处理大部分这些操作,所以开发者就能更多的专注在应用的业务逻辑上,更少地编写那些重复性的、易错的、低级的代码。
在AngularJS简化开发的同时,它也为客户端带来了一些精巧的技术,它们包括:
1.数据、业务逻辑、视图的分离
2.数据和视图的自动绑定
3.通用服务
4.依赖注入(主要用于聚合服务)
5.可扩展的HTML编译器(完全由JavaScript编写)
6.易于测试
7.客户端对这些技术的需求其实已经存在很久了。
同时,你还可以用AngularJS来开发单页或者多页的应用,不过其主要还是用来开发单页的。 AngularJS支持浏览器的历史操作,向前,向后按钮,单页应用中的收藏操作。
接下来,我们来详细讲解angularJS的模块。
大部分应用都有一个主方法用来实例化、组织、启动应用。AngularJS应用没有主方法,而是使用模块来声明应用应该如何启动。这种方式有以下几个优点:
1.启动过程是声明式的,所以更容易懂。
2.在单元测试是不需要加载全部模块的,因此这种方式有助于写单元测试。
3.可以在特定情况的测试中增加额外的模块,这些模块能更改配置,能帮助进行端对端的测试。
4.第三方代码可以打包成可重用的模块。
5.模块可以以任何先后或者并行的顺序加载(因为模块的执行本身是延迟的)。
举个例子:
&!doctype html&
&html ng-app="myApp"&
&script src="http://code.angularjs.org/angular-1.0.2.min.js"&&/script&
var myAppModule = angular.module('myApp', []);
      // configure the module.
      // in this example we will create a greeting filter
      myAppModule.filter('greet', function() {
        return function(name) {
          return 'Hello, ' + name + '!';
        };
      });
{{ 'World' | greet }}
上面的例子,我们是通过在&html ng-app="myApp"&中进行指定,来实现使用myApp这个模块启动应用的。
以上这个例子写法很简单,但是不适合用同样的写法来写大型应用。我们推荐是将你的应用拆分成以下几个模块:
1.一个服务模块,用来做服务的声明。
2.一个指令模块,用来做指令的声明。
3.一个过滤器模块,用来做过滤器声明。
4.一个依赖以上模块的应用级模块,它包含初始化代码。
举个例子:
&!doctype html&
&html ng-app="xmpl"&
&script src="http://code.angularjs.org/angular-1.0.2.min.js"&&/script&
&script src="script.js"&&/script&
&div ng-controller="XmplController"&
{{ greeting }}!
script.js:
angular.module('xmpl.service', []).
//服务模块
value('greeter', {
//自定义greeter对象
salutation: 'Hello',
localize: function(localization) {
this.salutation = localization.
greet: function(name) {
return this.salutation + ' ' + name + '!';
value('user', {
//自定义user对象
load: function(name) {
this.name =
angular.module('xmpl.directive', []);
//指令模块
angular.module('xmpl.filter', []);
//过滤器模块
angular.module('xmpl', ['xmpl.service', 'xmpl.directive', 'xmpl.filter']).
//模块xmpl依赖于数组中的模块
run(function(greeter, user) {
// 初始化代码,应用启动时,会自动执行
greeter.localize({
salutation: 'Bonjour'
user.load('World');
// A Controller for your app
var XmplController = function($scope, greeter, user) {
$scope.greeting = greeter.greet(user.name);
这样拆分的原因是,在你的测试中常常需要忽略掉初始化代码,因为这些代码比较难测试。通过把它拆分出来就能在测试中方便地忽视掉它。通过只加载和当前测试相关的模块,也能使测试更专一。以上只是一个建议,你可以放心根据你的具体情况来调整。
一个模块就是一系列配置和代码块的集合,它们是在启动阶段就附加到应用上的。一个最简单的模块由两类代码块集合组成的:
配置代码块 - 在注入提供者注入和配置阶段执行。只有注入提供者和常量可以被注入到配置块中。这是为了防止服务在被配置好之前就被提前初始化。
运行代码块 - 在注入器被创建后执行,被用来启动应用的。只有实例和常量能被注入到运行块中。这是为了防止在运行后还出现对系统的配置。
代码实现:
angular.module('myModule', []).
  config(function(injectables) { // provider-injector
配置代码块
    // This is an example of config block.
    // You can have as many of these as you want.
    // You can only inject Providers (not instances)
    // into the config blocks.
  }). run(function(injectables) { // instance-injector
运行代码块
    // This is an example of a run block.
    // You can have as many of these as you want.
    // You can only inject instances (not Providers)
    // into the run blocks
模块还有一些配置的简便方法,使用它们的效果等同于使用代码块。举个例子:
angular.module('myModule', []).
value('a', 123).
factory('a', function() { return 123; }).
directive('directiveName', ...).
filter('filterName', ...);
// is same as
angular.module('myModule', []).
config(function($provide, $compileProvider, $filterProvider) {
$provide.value('a', 123)
$provide.factory('a', function() { return 123; })
$compileProvider.directive('directiveName', ...).
$filterProvider.register('filterName', ...);
配置块会按照$provide, $compileProvider, $filterProvider,注册的顺序,依次被应用。唯一的例外是对常量的定义,它们应该始终放在配置块的开始处。
运行块是AngularJS中最像主方法的东西。一个运行块就是一段用来启动应用的代码。它在所有服务都被配置和所有的注入器都被创建后执行。运行块通常包含了一些难以测试的代码,所以它们应该写在单独的模块里,这样在单元测试时就可以忽略它们了。
模块可以把其他模块列为它的依赖。“依赖某个模块”意味着需要把这个被依赖的模块在本块模块之前被加载。换句话说被依赖模块的配置块会在本模块配置块前被执行。运行块也是一样。任何一个模块都只能被加载一次,即使它被多个模块依赖。
模块是一种用来管理$injector配置的方法,和脚本的加载没有关系。现在网上已有很多控制模块加载的库,它们可以和AngularJS配合使用。因为在加载期间模块不做任何事情,所以它们可以以任意顺序或者并行方式加载
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具原版地址:
  Directive是教玩一些新把戏的途径。在编译期间,匹配并执行。这允许注册行为或者转换结构。
  Angular自带一组内置的,对于建立有很大帮助。继续扩展的话,可以在定义领域特定语言(domain&specific&language&,DSL)。
一、在中引用
  Directive有驼峰式(camel&cased)的风格的命名,如(放在属性里貌似用不了)。但也可以支蛇底式的命名(),需要通过(冒号)、(减号)或(下划线)连接。作为一个可选项,可以用&&或者&&作为前缀,以满足验证需要。这里列出的合法命名:
data-ng-bind
  Directive可以放置于元素名、属性、、注释中。下面是引用这个的等价方式。(但很多都限制为&属性&的使用方式)
&span my-dir="exp"&&/span&
&span class="my-dir:"&&/span&
&my-dir&&/my-dir&
&!-- directive: my-dir exp --&
  Directive可以通过多种方式引用,下面列出种等价的方式:
&!DOCTYPE HTML&
&html lang="zh-cn" ng-app&
&meta charset="UTF-8"&
&title&invoke-directive&/title&
&style type="text/css"&
.ng-cloak {
display: none;
&div ng-controller="MyCtrl"&
Hello &input ng-model="name"/&&hr/&
ngBind="name" 这个用不了~~ &span ngBind="name"&&/span&&br/&
ng:bind="name"&span ng:bind="name"&&/span&&br/&
ng_bind="name"&span ng_bind="name"&&/span&&br/&
ng-bind="name"&span ng-bind="name"&&/span&&br/&
data-ng-bind="name"&span data-ng-bind="name"&&/span&&br/&
x-ng-bind="name"&span x-ng-bind="name"&&/span&&br/&
&script src="../angular-1.0.1.js" type="text/javascript"&&/script&
&script type="text/javascript"&
function MyCtrl($scope) {
$scope.name = "beauty~~";
二、String&interpolation
  在编译过程中,通过服务匹配文本与属性中的嵌入表达式(如)。这些表达式将会注册为,并且作为之前不是吗?!的一部分,一同更新。下面是一个简单的:
&img src="img/{{username}}.jpg"/&Hello {{username}}!
三、Compilation&process,&and&directive&matching
  HTML&编译&的三个步骤:
  1.&首先,通过浏览器的标准,将转换为对象。这是很重要的一步。因为模版必须是可解析(符合规范)的。这里可以跟大多数的模版系统做对比,它们一般是基于字符串的,而不是基于元素的。
  2.&对的编译()是通过调用方法完成的。这个方法遍历,对进行匹配。如果匹配成功,那么它将与对应的一起,加入到列表中。只要所有与指定关联的被识别出来,他们将按照优先级排序,并按照这个顺序执行他们的函数。的编译函数(),拥有一个修改结构的机会,并负责产生的解析。方法返回一个组合的,是所有自身的返回的的集合。
  3.&通过上一步返回的,将模版与连接起来。这反过来会调用自身的,允许它们在元素上注册一些监听器(),以及与一起建立一些。这样得出的结果,是在与之间的一个双向、即时的绑定。发生改变时,会得到对应的响应。
var $compile = ...; // injected into your code
var scope = ...;
var html = '&div ng-bind='exp'&&/div&';
// Step 1: parse HTML into DOM element
var template = angular.element(html);
// Step 2: compile the template
var linkFn = $compile(template);
// Step 3: link the compiled template with the scope.
linkFn(scope);
四、Reasons&behind&the&compile/link&separation
  在这个时候,你可能会想知道为什么编译进程会划分为和两个步骤。为了明白这一点,让我们看看一个真实的例子()
Hello {{user}}, you have these actions:
&li ng-repeat="action in user.actions"&{{action.description}}&/li&
  简单地讲,之所以分开和两步,是因为有时候需要在改变后,对应的结构也需要改变的情况,如。
  当上面的例子被编译时,编译器会遍历所有节点以寻找。是一个的例子。又是另外一个。但有一个难点。它需要能够很快地为每一个在中的制造出新的的能力。这意味着它为了满足克隆并且嵌入特定的(这里是指的的其中一个值)的目的,需要保持一个干净元素的拷贝,元素需要被克隆和插入元素。但仅仅克隆元素是不够的。还需要编译,以便它的(descriptions}})能够在正确的中被解析。原始的方法,一般会简单地插入一个元素的拷贝,然后编译它。但编译每一个元素的拷贝会比较缓慢,因为编译过程需要我们遍历节点树,查找并运行它们。如果我们有一个编译,需要通过对个进行处理,那么我们将陷入性能问题。
  问题的解决方案,是将编译过程分解为两个步骤。阶段识别出所有,并且将它们按照优先级进行排序,在阶段将特定的与特定的绑定在一起。
  ngRepeat将各个分开编译以防止编译过程落入元素中。元素的编译结果是一个包含所有包含在元素中的的,准备与特定元素的拷贝进行连接。在运行时,监测表达式,并作为一个,被加入到一个元素拷贝的数组,为克隆好的元素创建新的,并调用该拷贝对应的。
  总结:
编译函数编译函数在中是比较少见的,因为大多数只关心与指定的元素工作,而不是改变元素的模版(自身以及内部的结构)。为了优化性能,一些可以被实例共享的操作,可以移动到函数中。
连接函数极少是没有的。允许在指定的拷贝后的元素实例上注册监听器,也可以将中特定内容复制到中。
五、写一个(简易版)
  在这个例子里面,我们将建立一个根据输入格式,显示当前时间的
&!DOCTYPE HTML&
&html lang="zh-cn" ng-app="TimeFormat"&
&meta charset="UTF-8"&
&title&time-format&/title&
&div ng-controller="MyCtrl" id="main"&
Date format: &input ng-model="format" type="text"/&&hr/&
&!--下面使用属性x-current-time,是为了试试上面说的合法命名~~current:time、current-time、current_time、data-current-time -_-!!! --&
Current time is : &span x-current-time="format" id="myFormat"&&/span&&br/&
&button ng-click="remove()"&remove the span&/button&
&script src="../angular-1.0.1.js" type="text/javascript"&&/script&
&script type="text/javascript"&
angular.module("TimeFormat", [])
//在TimeFormat应用中注册&currentTime&这个directive的工厂方法
//前文提到过,依赖注入,可以直接在function的参数中写入,这里注入了$timeout、dataFilter
.directive("currentTime", function (dateFilter) {
//这个是上面提到的linking function。(不需要添加compile function,为啥?。。。)
return function (scope, element, attr) {
var intervalId;
//更新对应element的text值,即更新时间
function updateTime() {
element.text(dateFilter(new Date(), scope.format));
//通过watch,监控span对象的currentTime的值(是format这个model值,即input的值!!)
//这个方法仅仅在format发生改变的时候执行
scope.$watch(attr.currentTime, function (value) {
scope.format =
updateTime();
//当span被去掉的时候,取消更新
element.bind("$destroy", function () {
clearInterval(intervalId);
intervalId = setInterval(updateTime, 1000);
}).controller("MyCtrl",function($scope,$rootScope) {
$scope.format = "M/d/yy h:mm:ss a";
$scope.remove = function() {
var oFormat = document.getElementById("myFormat");
if(oFormat) {
angular.element(oFormat).remove();//通过这种方式调用remove,可以触发$destroy事件啊!!!试了我N久。。。
六、写一个(详细版)
  下面是一个创建样例(对象定义模版)。想看详细列表,请继续往下看。
var myModule = angular.module(...);
myModule.directive('directiveName', function factory(injectables) {
var directiveDefinitionObject = {
  priority: 0,
  template: '&div&&/div&',
  templateUrl: 'directive.html',
  replace: false,
  transclude: false,
  restrict: 'A',
  scope: false,
  compile: function compile(tElement, tAttrs, transclude) {
    return {
      pre: function preLink(scope, iElement, iAttrs, controller) { ... },
      post: function postLink(scope, iElement, iAttrs, controller) { ... }
  link: function postLink(scope, iElement, iAttrs) { ... }
return directiveDefinitionO
  在大多数场景下,我们并不需要精确控制,所以上面的定义是可以化简的。定义模版中的每一部分,将在下面章节讲解。在这个章节,我们仅仅关注定义模版的异构体(isomers&of&this&skeleton,没看懂。。。期待大家补充)。
  简化代码的第一步是依赖默认值。因此,上面的代码可以简化为:
var myModule = angular.module(...);
myModule.directive('directiveName', function factory(injectables) {
  var directiveDefinitionObject = {
    compile: function compile(tElement, tAttrs) {
      return function postLink(scope, iElement, iAttrs) { ... }
  return directiveDefinitionO
  大多数只关心实例,而不是模版转换,所以可以进一步化简(翻译得很勉强。。。期待大家补充):
var myModule = angular.module(...);
myModule.directive('directiveName', function factory(injectables) {
  return function postLink(scope, iElement, iAttrs) { ... }
七、工厂方法
  工厂方法负责创建。它仅仅使用一次,就在第一次匹配到的时候。你可以在这里执行一些初始化操作。工厂方法通过执行,让它遵守所有注入声明规则(),让其变为可注入的。
八、directive定义对象说明
  directive定义对象提供了的结构。属性如下:
name&-&当前的名称,注册时可以使用默认值(不填)。
priority(优先级)- 当有多个定义在同一个元素时,有时需要明确它们的执行顺序。这属性用于在的调用之前进行排序。如果优先级相同,则执行顺序是不确定的(经初步试验,优先级高的先执行,同级时按照类似栈的&后绑定先执行&。另外,测试时有点不小心,在定义的时候,两次定义了一个相同名称的,但执行结果发现,两个或者都会执行)。
terminal(最后一组)如果设置为&true&,则表示当前的将会成为最后一组执行的。任何与当前的优先级相同的话,他们依然会执行,但顺序是不确定的(虽然顺序不确定,但基本上与的顺序一致。当前优先级执行完毕后,更低优先级的将不会再执行)。
scope&-&如果设置为:
true&-&将为这个创建一个新的。如果在同一个元素中有多个需要新的的话,它还是只会创建一个。新的作用域规则不适用于根模版(),因此根模版往往会获得一个新的。
{}(object&hash)&-&将创建一个新的、独立的。&isolate&&scope与一般的的区别在于它不是通过原型继承于父的。这对于创建可复用的组件是很有帮助的,可以有效防止读取或者修改父级的数据。这个独立的会创建一个拥有一组来源于父的本地属性的。这些对于为模版创建值的别名很有帮助()。本地的定义是对其来源的一组本地的映射:
@或建立一个到属性的绑定。因为属性值总是类型,所以这个值总是返回一个字符串。如果没有通过指定属性名称,那么本地名称将与属性的名称一直。例如&hello&{{name}}&&,的定义为:&@myAttr&}。那么,的会映射出&hello&{{name}}"转换后的真实值。属性值改变后,的属性也会相应地改变(仅仅单向,与下面的&=&不同)。属性是在父读取的(不是组件)
=或(这里也许是)&在本地属性与属性之间设置双向的绑定。如果没有指定名称,那么本地名称将与属性名称一致。例如&parentModel&&,定义的为:&=myAttr&},那么&localName&将会映射父的&&。如果发生任何改变,也会发生改变,反之亦然。(双向绑定)
&或提供一个在父上下文中执行一个表达式的途径。如果没有指定的名称,那么将与属性名称一致。例如&count&=&count&+&value&&,的定义为:&increment()&},那么&localFn&会指向一个包裹着表达式的。一般来说,我们希望通过一个表达式,将数据从传到中。这可以通过传送一个本地变量键值的映射到表达式的函数中来完成。例如,如果表达式是,那么我们可以通过的方式调用以指定的值(上面的例子真的没看懂,跑哪去了?)。
controller&-&controller&构造函数。会在步骤之前进行初始化,并允许其他通过指定名称的进行共享(看下面的属性)。这将允许之间相互沟通,增强相互之间的行为。默认注入了以下本地对象:
$scope&-&与当前元素结合的
$element&-&当前的元素
$attrs&-&当前元素的属性对象
$transclude&-&一个预先绑定到当前转置的转置。A&transclude&linking&function&pre-bound&to&the&correct&transclusion&scope)
require&-&请求另外的,传入当前的中。需要传入一个的名称。如果找不到这个名称对应的,那么将会抛出一个。名称可以加入以下前缀:
?&-&不要抛出异常。这使这个依赖变为一个可选项。
^&-&允许查找父元素的
restrict&-&EACM的子集的字符串,它限制为指定的声明方式。如果省略的话,将仅仅允许通过属性声明:
E&-&元素名称:&
A&-&属性名:&&exp&&&/div&
C&-&class名:&&my-directive:&&&/div&
M&-&注释&:&
template&- 如果为,则将模版内容替换当前的元素,并将原来元素的属性、一并迁移;如果为,则将模版元素当作当前元素的子元素处理。想了解更多的话,请查看&Creating&Widgets&章节(在哪啊。。。就有。。。)
templateUrl&-&与基本一致,但模版通过指定的进行加载。因为模版加载是异步的,所以、都会暂停,等待加载完毕后再执行。
replace&-&如果设置为,那么模版将会替换当前元素,而不是作为子元素添加到当前元素中。(注:为时,模版必须有一个根节点)
transclude&-&编译元素的内容,使它能够被所用。需要(在模版中)配合使用(引用)。的优点是能够得到一个预先与当前绑定的。一般地,建立一个,创建,不是子级的,而是的兄弟。这将使得拥有私有的状态,会被绑定到父级()中。(上面那段话没看懂。但实际实验中,如果通过调用,而设置为或者字符串且中包含的时候,将会将的编译结果插入到的内容中。如果的内容没有被标签包裹,那么结果中将会多了一个。如果本来有其他东西包裹的话,将维持原状。但如果设置为&element&的话,的整体内容会出现在中,且被包裹)
true&-&转换这个的内容。(这个感觉上,是直接将内容编译后搬入指定地方)
&element&&-&转换整个元素,包括其他优先级较低的。(像将整体内容编译后,当作一个整体(外面再包裹),插入到指定地方)
compile&-&这里是,将在下面章节详细讲解
link&-&这里是,将在下面章节详细讲解。这个属性仅仅是在属性没有定义的情况下使用。
九、Compile&function
function compile ( tElement, tAttrs, transclude) { & }
  compile function用于处理DOM模版的转换。由于大多数directive都不需要转换模版,所以compile不会经常被使用到。需要compile function的directive,一般是那种需要转换DOM模版的(如ngRepeat),或者是需要异步加载内容的(如ngView)。compile function拥有一下的参数:
tElement - 模版元素 & 使用当前directive的元素。仅仅在当前元素或者当前元素子元素下做模版转换是安全的。
tAttrs - 模版属性 - 标准化的属性,在当前元素声明的,可以在各个directive之间共享。详情请看Attributes章节
transclude & 一个转换用的linking function:& function(scope,cloneLinking).
  注意:如果template被克隆过,那么template实例和link实例不能是同一个object。为此,在compile function中做任何除了DOM转换以外的事情,是不安全的,这将应用到所有克隆中。特别是,DOM事件监听器的注册的操作,应该在linking function中进行,而不是compile function。
  compile function 可以有一个返回值,类型可以是function或者object。
返回function & 通常在不需要compile function(为空)时使用,等同于通过link(directive定义模版的属性)注册linking function。
返回包含pre、post属性的object - 允许我们控制在linking phase期间何时调用linking function。详情请看下面关于pre-linking、post-linking function的章节。
十、Linking function
function link( scope, iElement, iAttrs, controller) { & }
  link function负责注册DOM事件监听器,也可以进行DOM的更新操作。link function会在模版克隆操作完毕之后执行。这里存放着directive大多数的逻辑。
scope - Scope - 被directive用于注册watches()。
iElement - 元素实例 - directive使用的元素。只有在postLink function里面对子元素进行操作,才是安全的。因为子元素已经被link(与model连接吗?!)。
iAttrs - 属性实例 - 标准的当前元素的属性列表。在所有directive的linking function之间分享的。
controller - controller实例 - 如果在当前元素的directive中,有其中一个定义了controller,那么可以在这里获取到该controller的实例。这个controller是在所有directive之间共享的,允许各个directive将controller当作一个它们之间沟通频道。
Pre-link function
  在子元素linked之前执行。在这里做DOM转换是不安全的,因为compiler的linking function在link时可能会定位不到正确的元素。
Post-link function
  在子元素linked之后执行。在这里执行DOM转换是安全的。
十一、Attributes
  attribute&object&-&在或中作为参数&是一个访问以下东东的途径:
标准化的属性名称:由于,例如,可以表现为多种形式,如&ng:bind&、&x-ng-bind&&&这个对象允许我们通过标准命名(驼峰式)访问属性。
directive&之间通讯:所有共享一个对象实例,使得可以通过对象进行之间的内部通讯。
支持:属性是分配到对象中,允许其他读取该。
观察属性:通过去观察属性值的变化,包括(例如&{{bar}}&)。不单单很有效,而且是简单地获取真实值唯一的办法。因为在阶段,还没被赋值(替换真实值),所以在这时候访问它,结果是。
&!DOCTYPE HTML&
&html lang="zh-cn" ng-app="DirectiveProperty"&
&meta charset="UTF-8"&
&title&directive-attribute-test&/title&
&style type="text/css"&
.ng-cloak {
display: none;
&body ng-controller="MyCtrl"&
&input type="text" ng-model="name" value="myName"/&
&p my-attr="123" directive-p2 attr-dd="{{name}}"&&/p&
&script src="../angular-1.0.1.js" type="text/javascript"&&/script&
&script type="text/javascript"&
var app = angular.module("DirectiveProperty", []);
app.controller("MyCtrl", function ($scope) {
$scope.name = "my little dada";
var directiveP2 = app.directive("directiveP2", function () {
link:function postLink(scope,lEle,lAttr) {
console.log("myAttr:" + lAttr.myAttr);//123
console.log("myAttr:" + lAttr.attrDd);//undefinded
lAttr.$observe('attrDd', function(value) {
console.log('attrDd has changed value to ' + value); //my little dada
//除此以外,还可啥办法可以拿到这个值啊。。。¥&()@#&¥(@#
十二、理解和
  我们经常需要一些可重用的组件。下面是一段伪代码,展示一个简单的组件如何能够工作。
&button ng-click="show=true"&show&/button&
&dialog title="Hello {{username}}."
visible="show"
on-cancel="show = false"
on-ok="show = doSomething()"&
Body goes here: {{username}} is {{title}}.
  点击&&按钮将会打开。有一个标题,与数据&&绑定,还有一段我们想放置在内部的内容。
  下面是一段为了而编写的模版定义:
&div ng-show="show()"&
&h3&{{title}}&/h3&
&div class="body" ng-transclude&&/div&
&div class="footer"&
&button ng-click="onOk()"&Save changes&/button&
&button ng-click="onCancel()"&Close&/button&
  这将无法正确渲染,除非我们对做一些特殊处理。
  第一个我们需要解决的问题是,模版期望会被定义,而在初始化时会与绑定。此外,按钮需要、两个出现在里面。这限制了插件的效能(。。。)。为了解决映射问题,通过如下的本地方法(,估计在说定义模版中的)去创建模版期待的本地变量:
title: 'bind', // set up title to accept data-binding
onOk: 'expression', // create a delegate onOk function
onCancel: 'expression', // create a delegate onCancel function
show: 'accessor' // create a getter/setter function for visibility.
  在控件中创建本地属性,带来了两个问题:
  1.&isolation(属性隔离?)&如果用户忘记了在控件模版设置这个元素属性,那么将会与祖先的属性&&(如有)绑定。这是不可预知、不可取的。
  2.&transclusion&-&transcluded&DOM可以查看控件的(),会覆盖中真正需要绑定的属性。在我们的例子中,插件中的属性破坏了的属性。
  为了解决这个缺乏属性隔离的问题,我们需要为这个定义一个。不是通过从(这里为啥是?不是吗?)原型继承的,所以我们无需担心属性冲突问题(作为当前scope的兄弟)。
  然而,带来了一个新问题:如果是控件的的一个子元素,那么他将不能与任何东西绑定()。因此,是原始的一个子,在控件为本地属性而创建之前创建的。与控件属于兄弟节点(树中)。
  这也许看起来会有点意想不到的复杂,但这样做让控件用户与控件开发者至少带来了惊喜。(解决了问题)
  因此,最终的定义大致如下:
transclude:true,
title: 'bind', // set up title to accept data-binding
onOk: 'expression', // create a delegate onOk function
onCancel: 'expression', // create a delegate onCancel function
show: 'accessor' // create a getter/setter function for visibility.
//我试过这么整,失败&&请继续往下看
  我尝试把上面的代码拼凑成一个完整的例子。直接复制的话,无法达到预期效果。但稍作修改后,插件可以运行了。
&!DOCTYPE html&
&html ng-app="Dialog"&
&meta http-equiv="Content-Type" content="text/ charset=utf-8"/&
&title&directive-dialog&/title&
&meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"&
&script src="../angular.js" type="text/javascript"&&/script&
&div ng-controller="MyCtrl"&
&button ng-click="show=true"&show&/button&
&dialog title="Hello {{username}}"
visible="{{show}}"
on-cancel="show="
on-ok="show=methodInParentScope();"&
&!--上面的on-cancel、on-ok,是在directive的isoloate scope中通过&引用的。如果表达式中包含函数,那么需要将函数绑定在parent scope(当前是MyCtrl的scope)中--&
Body goes here: username:{{username}} , title:{{title}}.
&!--这里还可以这么玩~names是parent scope的--&
&li ng-repeat="name in names"&{{name}}&/li&
&script type="text/javascript"&
var myModule = angular.module("Dialog", []);
myModule.controller("MyCtrl", function ($scope) {
$scope.names = ["name1", "name2", "name3"];
$scope.show = false;
$scope.username = "Lcllao";
$scope.title = "parent title";
$scope.methodInParentScope = function() {
alert("记住。。scope里面通过&定义的东东,是在父scope中玩的!!。。。");
myModule.directive('dialog', function factory() {
priority:100,
template:['&div ng-show="visible"&',
&h3&{{title}}&/h3&',
&div class="body" ng-transclude&&/div&',
&div class="footer"&',
&button ng-click="onOk()"&OK&/button&',
&button ng-click="onCancel()"&Close&/button&',
'&/div&'].join(""),
replace:false,
transclude: true,
restrict:'E',
title:"@",//引用dialog标签title属性的值
onOk:"&",//以wrapper function形式引用dialog标签的on-ok属性的内容
onCancel:"&",//以wrapper function形式引用dialog标签的on-cancel属性的内容
visible:"@"//引用dialog标签visible属性的值
十三、Creating&Components
  我们通常会期望通过复杂的结构替换掉(所在的元素?目的大概是使内部复杂点,看起来牛点)。这让成为使用可复用组件的建立应用的一个快捷方式。
  下面是一个可复用组件的例子:
&!DOCTYPE html&
&html ng-app="ZippyModule"&
&meta http-equiv="Content-Type" content="text/ charset=utf-8"/&
&title&ZippyModule&/title&
&meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"&
&style type="text/css"&
border: 1px solid black;
display: inline-block;
width: 250px;
.zippy.opened & .title:before { content: '▼ '; }
.zippy.opened & .body { display: block; }
.zippy.closed & .title:before { content: '? '; }
.zippy.closed & .body { display: none; }
.zippy & .title {
background-color: black;
color: white;
padding: .1em .3em;
cursor: pointer;
.zippy & .body {
padding: .1em .3em;
&script src="../angular.js" type="text/javascript"&&/script&
&div ng-controller="MyCtrl"&
Title: &input ng-model="title" type="text"&&br/&
Text: &textarea ng-model="text" &&/textarea&
&div class="zippy" zippy-title="Details: {{title}}..."&{{text}}&/div&
&script type="text/javascript"&
var myModule = angular.module("ZippyModule", []);
myModule.controller("MyCtrl", function ($scope) {
$scope.title = "这里是标题";
$scope.text = "这里是内容哇。。。";
myModule.directive('zippy', function () {
template: '&div&' +
&div class="title"&{{title}}&/div&' +//这个title属于当前directive isolate scope的property
&div class="body" ng-transclude&&/div&' + //这里的东西,获取的是父scope的property咯
replace:true,
transclude: true,
restrict:'C',
title:"@zippyTitle"//绑定directive元素身上的zippy-title属性
link:function(scope,element,attrs) {
var title = angular.element(element.children()[0]),
opened = false;
title.bind("click", toogle);
element.addClass("closed");
function toogle() {
opened = !
element.removeClass(opened ? "closed" : "opened");
element.addClass(opened ? "opened" : "closed");
历时N天。。。这玩意终于啃完了!!!明天开始下一篇!
阅读(...) 评论()

我要回帖

更多关于 angularjs2 的文章

 

随机推荐