Angular JS - Modularize

Edit

Angular JS模块化,主要借助于3个方式:directive, component, module

directive & 3 bindings

2-way binding “=”

function MyDirective() {
var ddo = {
scope: {
myProp: '=attributeName'
}
...
};
return ddo;
}
<!-- index.html -->
<my-directive attribute-name="outerProp">
</my-directive>
<!-- directive.html -->
<p>{{my-prop}}</p>

所有对attribute-name或者my-prop的改动,两个html里都会做同步修改

1-way binding “<” and “@”

function MyDirective() {
var ddo = {
scope: {
prop: '<',
},
...
};
return ddo;
}

与上面不同,这里只有index.html才能修改prop。

function MyDirective() {
var ddo = {
scope: {
prop: '@',
},
...
};
return ddo;
}

这里prop就只能绑定index.html里的属性变量,如下

<my-directive my-attribute="{{outerProp}}">
</my-directive>

可见my-attribute里面不能有变量(例如controller或者controller的成员)。而且和’<’类似,’@’也是单向的。

简化版的directive - component

angular.module('App', [])
.component('myComponent', {
templateUrl: 'template.html',
controller: CompController,
bindings: {
prop1: '<',
prop2: '@',
onAction: '&'
}
});

语法基本与directive类似,用bindings取代了scope。

‘bindings’ object is the isolate scope param mapping definition.

isolate scope里面没有双向绑定了,明确了输入输出:

  • ‘<’, ‘@’作为输入
  • ‘&’作为输出,意思是通过用’&’注册callback来将输出送到相应的模块

使用’&’的基本方法

调用component的DOM写法。

<my-component
prop1="val-1"
prop2="@parentProp"
on-action="parentFunction(myArg)">
{{ $ctrl.prop1.prop }} and {{ $ctrl.prop2 }}
</my-component>

template的写法,component的写法如上一节的例子。

<div
ng-click="$ctrl.onAction({myArg: 'val'})">
{{ $ctrl.prop1.prop }} and {{ $ctrl.prop2 }}
</div>

注意:

  • onAction在标签里的写法是on-action
  • myArg在template中是key name。value值可以来自于controller($ctrl),亦或bindings中的’<’, ‘@’,方法如下,通过inject controller。
angular.module('MenuApp')
.controller('ItemListController', ItemListController)
ItemListController.$inject = ['items']
function ItemListController(items, currentItem) {
var list = this
list.items = items
}

Components Lifecycle

  • $onInit – controller initialization code
  • $onChanges(changeObj) – called whenever one-way bindings are updated
    • changeObj.currentValue, changeObj.previousValue
  • $postLink – similar to ‘link’ in directive
  • $onDestroy – when scope is about to be destroyed

Link for directive

  • DOM manipulation is usually done inside of the link function
    • Declared on the DDO
  • Link function does not support injection
    • To use injected components, services, inject them into directive
  • ‘scope’ parameter is the exact $scope in directive’s controller
  • ‘element’ object represents the element of the directive
    • Top level element
    • It’s jqLite object or jQuery object (if jQuery is included)

module

A module is a collection of services, directives, controllers, filters, and configuration information. angular.module is used to configure the $injector.

Create the module without dependency.

angular.module('module2', [])

Create with dependency.

angular.module('module3',
['module1', 'module2']);

Retrieve the module.

angular.module('module1')

ng-app = main module

<!DOCTYPE html>
<html ng-app='module3'>
</html>

Config and Run

angular.module('module1')
.config(function () {
// Inject only Providers and constants
});
angular.module('module1')
.run(function () {
// Inject only instances (like services) and constants.
});
  • module.config method fires before module.run method
  • All dependency modules get configured first
  • It doesn’t matter which modules are listed first as long as module declarations are listed before artifact declarations on that module

模块化

Splitting Javascript into Several Files.
每一个文件只包含一个artifact。在HTML中引入。

%23Angular%20JS%20-%20Modularize%0A@%28myblog%29%5Bangular%2C%20javascript%5D%0A%0AAngular%20JS%u6A21%u5757%u5316%uFF0C%u4E3B%u8981%u501F%u52A9%u4E8E3%u4E2A%u65B9%u5F0F%uFF1Adirective%2C%20component%2C%20module%0A%0A%23%23%20directive%20%26%203%20bindings%0A%23%23%23%202-way%20binding%20%22%3D%22%0A%60%60%60%0Afunction%20MyDirective%28%29%20%7B%0A%20%20var%20ddo%20%3D%20%7B%0A%09%20%20scope%3A%20%7B%0A%09%20%20%20%20myProp%3A%20%27%3DattributeName%27%0A%09%20%20%7D%0A%09%20%20...%0A%20%20%7D%3B%0A%20%20return%20ddo%3B%0A%7D%0A%60%60%60%0A%60%60%60%0A%3C%21--%20index.html%20--%3E%0A%3Cmy-directive%20attribute-name%3D%22outerProp%22%3E%0A%3C/my-directive%3E%0A%0A%3C%21--%20directive.html%20--%3E%0A%3Cp%3E%7B%7Bmy-prop%7D%7D%3C/p%3E%0A%60%60%60%0A%u6240%u6709%u5BF9attribute-name%u6216%u8005my-prop%u7684%u6539%u52A8%uFF0C%u4E24%u4E2Ahtml%u91CC%u90FD%u4F1A%u505A%u540C%u6B65%u4FEE%u6539%0A%23%23%23%201-way%20binding%20%22%26lt%3B%22%20and%20%22@%22%0A%60%60%60%0Afunction%20MyDirective%28%29%20%7B%0A%20%20var%20ddo%20%3D%20%7B%0A%09%20%20scope%3A%20%7B%0A%09%20%20%20%20prop%3A%20%27%26lt%3B%27%2C%0A%09%20%20%7D%2C%0A%09%20%20...%0A%20%20%7D%3B%0A%20%20return%20ddo%3B%0A%7D%0A%60%60%60%0A%u4E0E%u4E0A%u9762%u4E0D%u540C%uFF0C%u8FD9%u91CC%u53EA%u6709index.html%u624D%u80FD%u4FEE%u6539prop%u3002%0A%60%60%60%0Afunction%20MyDirective%28%29%20%7B%0A%20%20var%20ddo%20%3D%20%7B%0A%20%20scope%3A%20%7B%0A%20%20%20%20prop%3A%20%27@%27%2C%0A%20%20%7D%2C%0A%20%20...%0A%20%20%7D%3B%0A%20%20return%20ddo%3B%0A%7D%0A%60%60%60%0A%u8FD9%u91CCprop%u5C31%u53EA%u80FD%u7ED1%u5B9Aindex.html%u91CC%u7684%u5C5E%u6027%u53D8%u91CF%uFF0C%u5982%u4E0B%0A%60%60%60%0A%3Cmy-directive%20my-attribute%3D%22%7B%7BouterProp%7D%7D%22%3E%0A%3C/my-directive%3E%0A%60%60%60%0A%u53EF%u89C1my-attribute%u91CC%u9762%u4E0D%u80FD%u6709%u53D8%u91CF%uFF08%u4F8B%u5982controller%u6216%u8005controller%u7684%u6210%u5458%uFF09%u3002%u800C%u4E14%u548C%27%26lt%3B%27%u7C7B%u4F3C%uFF0C%27@%27%u4E5F%u662F%u5355%u5411%u7684%u3002%0A%0A%23%23%20%u7B80%u5316%u7248%u7684directive%20-%20component%0A%60%60%60%0Aangular.module%28%27App%27%2C%20%5B%5D%29%0A.component%28%27myComponent%27%2C%20%7B%0A%09templateUrl%3A%20%27template.html%27%2C%0A%09controller%3A%20CompController%2C%0A%09bindings%3A%20%7B%0A%09%09prop1%3A%20%27%26lt%3B%27%2C%0A%09%09prop2%3A%20%27@%27%2C%0A%09%09onAction%3A%20%27%26%27%0A%09%7D%0A%7D%29%3B%0A%60%60%60%0A%u8BED%u6CD5%u57FA%u672C%u4E0Edirective%u7C7B%u4F3C%uFF0C%u7528bindings%u53D6%u4EE3%u4E86scope%u3002%0A%3E%u2018bindings%u2019%20object%20is%20the%20isolate%20scope%20param%09mapping%20definition.%20%0A%0Aisolate%20scope%u91CC%u9762%u6CA1%u6709%u53CC%u5411%u7ED1%u5B9A%u4E86%uFF0C%u660E%u786E%u4E86%u8F93%u5165%u8F93%u51FA%uFF1A%0A-%20%27%26lt%3B%27%2C%20%27@%27%u4F5C%u4E3A%u8F93%u5165%0A-%20%27%26%27%u4F5C%u4E3A%u8F93%u51FA%uFF0C%u610F%u601D%u662F%u901A%u8FC7%u7528%27%26%27%u6CE8%u518Ccallback%u6765%u5C06%u8F93%u51FA%u9001%u5230%u76F8%u5E94%u7684%u6A21%u5757%0A%0A%23%23%23%20%u4F7F%u7528%27%26%27%u7684%u57FA%u672C%u65B9%u6CD5%0A%u8C03%u7528component%u7684DOM%u5199%u6CD5%u3002%0A%60%60%60%0A%3Cmy-component%0A%09prop1%3D%22val-1%22%0A%09prop2%3D%22@parentProp%22%0A%09on-action%3D%22parentFunction%28myArg%29%22%3E%0A%09%7B%7B%20%24ctrl.prop1.prop%20%7D%7D%20and%20%7B%7B%20%24ctrl.prop2%20%7D%7D%0A%3C/my-component%3E%0A%60%60%60%0Atemplate%u7684%u5199%u6CD5%uFF0Ccomponent%u7684%u5199%u6CD5%u5982%u4E0A%u4E00%u8282%u7684%u4F8B%u5B50%u3002%0A%60%60%60%0A%3Cdiv%0A%09ng-click%3D%22%24ctrl.onAction%28%7BmyArg%3A%20%27val%27%7D%29%22%3E%0A%09%7B%7B%20%24ctrl.prop1.prop%20%7D%7D%20and%20%7B%7B%20%24ctrl.prop2%20%7D%7D%0A%3C/div%3E%0A%60%60%60%0A%u6CE8%u610F%uFF1A%0A-%20onAction%u5728%u6807%u7B7E%u91CC%u7684%u5199%u6CD5%u662Fon-action%0A-%20myArg%u5728template%u4E2D%u662Fkey%20name%u3002value%u503C%u53EF%u4EE5%u6765%u81EA%u4E8Econtroller%28%24ctrl%29%uFF0C%u4EA6%u6216bindings%u4E2D%u7684%27%26lt%3B%27%2C%20%27@%27%uFF0C%u65B9%u6CD5%u5982%u4E0B%uFF0C%u901A%u8FC7inject%20controller%u3002%0A%0A%60%60%60%0Aangular.module%28%27MenuApp%27%29%0A.controller%28%27ItemListController%27%2C%20ItemListController%29%0A%0AItemListController.%24inject%20%3D%20%5B%27items%27%5D%0Afunction%20ItemListController%28items%2C%20currentItem%29%20%7B%0A%20%20var%20list%20%3D%20this%0A%20%20list.items%20%3D%20items%0A%7D%0A%60%60%60%0A%0A%23%23%23%20Components%20Lifecycle%0A-%20%24onInit%20%u2013%20controller%20initialization%20code%0A-%20%24onChanges%28changeObj%29%20%u2013%20called%20whenever%20one-way%20bindings%20are%20updated%0A%09-%20changeObj.currentValue%2C%20changeObj.previousValue%0A-%20%24postLink%20%u2013%20similar%20to%20%u2018link%u2019%20in%20directive%0A-%20%24onDestroy%20%u2013%20when%20scope%20is%20about%20to%20be%20destroyed%0A%0A%3E%20**Link%20for%20directive**%0A-%20DOM%20manipulation%20is%20usually%20done%20inside%20of%20the%20link%20function%0A%09-%20Declared%20on%20the%20DDO%0A-%20Link%20function%20does%20not%20support%20injection%0A%09-%20To%20use%20injected%20components%2C%20services%2C%20inject%20them%20into%20directive%0A-%20%u2018scope%u2019%20parameter%20is%20the%20exact%20%24scope%20in%20directive%u2019s%20controller%0A-%20%u2018element%u2019%20object%20represents%20the%20element%20of%20the%20directive%0A%09-%20Top%20level%20element%0A%09-%20It%u2019s%20jqLite%20object%20or%20jQuery%20object%20%28if%20jQuery%20is%20included%29%0A%0A%23%23%20module%0A%3EA%20module%20is%20a%20collection%20of%20services%2C%20directives%2C%20controllers%2C%20filters%2C%20and%20configuration%20information.%20angular.module%20is%20used%20to%20configure%20the%20%24injector.%0A%0ACreate%20the%20module%20without%20dependency.%0A%60%60%60%0Aangular.module%28%27module2%27%2C%20%5B%5D%29%0A%60%60%60%0ACreate%20with%20dependency.%0A%60%60%60%0Aangular.module%28%27module3%27%2C%0A%09%09%09%09%5B%27module1%27%2C%20%27module2%27%5D%29%3B%0A%60%60%60%0ARetrieve%20the%20module.%0A%60%60%60%0Aangular.module%28%27module1%27%29%0A%60%60%60%0Ang-app%20%3D%20main%20module%0A%60%60%60%0A%3C%21DOCTYPE%20html%3E%0A%3Chtml%20ng-app%3D%27module3%27%3E%0A%u2026%0A%3C/html%3E%0A%60%60%60%0A%0A%23%23%23%20Config%20and%20Run%0A%60%60%60%0Aangular.module%28%27module1%27%29%0A.config%28function%20%28%29%20%7B%0A%09//%20Inject%20only%20Providers%20and%20constants%09%0A%09%u2026%0A%7D%29%3B%0A%60%60%60%0A%0A%60%60%60%0Aangular.module%28%27module1%27%29%0A.run%28function%20%28%29%20%7B%0A%09//%20Inject%20only%20instances%20%28like%20services%29%20and%20constants.%0A%09%u2026%0A%7D%29%3B%0A%60%60%60%0A%0A-%20module.config%20method%20fires%20before%20module.run%20method%0A-%20All%20dependency%20modules%20get%20configured%20first%0A-%20It%20doesn%u2019t%20matter%20which%20modules%20are%20listed%20first%20as%20long%20as%20module%20declarations%20are%20listed%20before%20artifact%20declarations%20on%20that%20module%0A%0A%23%23%20%u6A21%u5757%u5316%0ASplitting%20Javascript%20into%20Several%20Files.%0A%u6BCF%u4E00%u4E2A%u6587%u4EF6%u53EA%u5305%u542B%u4E00%u4E2Aartifact%u3002%u5728HTML%u4E2D%u5F15%u5165%u3002%0A%21%5BAlt%20text%7C600x0%5D%28./1506329033574.png%29%0AHTML%u4E2D%u5F15%u5165script%uFF0C%u53EA%u662F%u4E00%u79CD%u9884%u7F16%u8BD1%uFF0C%u7C7B%u4F3CC%u8BED%u8A00%u7684include%uFF0C%u53EA%u4F1A%u628A%u5BF9%u5E94js%u6587%u4EF6%u7684%u4EE3%u7801%u76F4%u63A5%u63D2%u5165HTML%u6587%u4EF6%u3002%0A%0A