angular学习(十三)——Component
转载请写明来源地址:http://www.52php.cn/article/p-hqmpiisq-bph.html 理解Components在angularjs中,Component是一种特殊的directive,它的配置更简单一些,非常适合组件化的app架构。使用web组件和使用Angular风格的app架构使得编写app更为简便。 Component的优点:
不使用Component的情况
Components的创建和配置Components由angularjs的module使用
heroApp.html: <!DOCTYPE html>
<html>
<head>
<meta charset="uft-8"/>
<title></title>
</head>
<script src="script/angular.min.js"></script>
<body ng-app="heroApp">
<div ng-controller="MainCtrl as ctrl">
<b>Hero</b><br>
<hero-detail hero="ctrl.hero"></hero-detail>
</div>
</body>
<script> angular.module('heroApp',[]).controller('MainCtrl',function MainCtrl() { this.hero = { name: 'Spawn' }; }); function HeroDetailController() { } angular.module('heroApp').component('heroDetail',{ templateUrl: 'heroDetail.html',controller: HeroDetailController,bindings: { hero: '=' } }); </script>
</html>
heroDetail.html: <span>Name: {{$ctrl.hero.name}}</span>
Directive和Component之间的定义比较
组件化app架构如前所述,component使得使用组件化架构构建app更为容易,除此之外component还具备的能力具体如下:
Component树示例下面这个示例对上面对例子进行了扩展,并和我们刚讲过到概念结合起来: 不再使用ngController,现在使用拥有多个hero的heroList组件象,为每个hero创建一个heroDetail组件。 heroDetail组件包含的新功能:
heroApp.html <!DOCTYPE html>
<html>
<head>
<meta charset="uft-8"/>
<title></title>
</head>
<script src="script/angular.min.js"></script>
<body ng-app="heroApp">
<hero-list></hero-list>
</body>
<script> /** * index.js */ angular.module('heroApp',[]); /** * heroList.js */ function HeroListController($scope,$element,$attrs) { var ctrl = this; // This would be loaded by $http etc. ctrl.list = [ { name: 'Superman',location: '' },{ name: 'Batman',location: 'Wayne Manor' } ]; ctrl.updateHero = function(hero,prop,value) { hero[prop] = value; }; ctrl.deleteHero = function(hero) { var idx = ctrl.list.indexOf(hero); if (idx >= 0) { ctrl.list.splice(idx,1); } }; } angular.module('heroApp').component('heroList',{ templateUrl: 'heroList.html',controller: HeroListController }); /** * heroDetail.js */ function HeroDetailController() { var ctrl = this; ctrl.delete = function() { ctrl.onDelete({hero: ctrl.hero}); }; ctrl.update = function(prop,value) { ctrl.onUpdate({hero: ctrl.hero,prop: prop,value: value}); }; } angular.module('heroApp').component('heroDetail',bindings: { hero: '<',onDelete: '&',onUpdate: '&' } }); /** * editableField.js */ function EditableFieldController($scope,$attrs) { var ctrl = this; ctrl.editMode = false; ctrl.handleModeChange = function() { if (ctrl.editMode) { ctrl.onUpdate({value: ctrl.fieldValue}); ctrl.fieldValueCopy = ctrl.fieldValue; } ctrl.editMode = !ctrl.editMode; }; ctrl.reset = function() { ctrl.fieldValue = ctrl.fieldValueCopy; }; ctrl.$onInit = function() { // Make a copy of the initial value to be able to reset it later ctrl.fieldValueCopy = ctrl.fieldValue; // Set a default fieldType if (!ctrl.fieldType) { ctrl.fieldType = 'text'; } }; } angular.module('heroApp').component('editableField',{ templateUrl: 'editableField.html',controller: EditableFieldController,bindings: { fieldValue: '<',fieldType: '@?',onUpdate: '&' } }); </script>
</html>
heroList.html <b>Heroes</b><br>
<hero-detail ng-repeat="hero in $ctrl.list" hero="hero" on-delete="$ctrl.deleteHero(hero)" on-update="$ctrl.updateHero(hero,value)"></hero-detail>
heroDetail.html <hr> <div> Name: {{$ctrl.hero.name}}<br> Location: <editable-field field-value="$ctrl.hero.location" field-type="text" on-update="$ctrl.update('location',value)"></editable-field><br> <button ng-click="$ctrl.delete()">Delete</button> </div>
editableField.html <span ng-switch="$ctrl.editMode"> <input ng-switch-when="true" type="{{$ctrl.fieldType}}" ng-model="$ctrl.fieldValue"> <span ng-switch-default>{{$ctrl.fieldValue}}</span> </span> <button ng-click="$ctrl.handleModeChange()">{{$ctrl.editMode ? 'Save' : 'Edit'}}</button> <button ng-if="$ctrl.editMode" ng-click="$ctrl.reset()">Reset</button>
Component作为route模版当使用ngRoute时,Component作为route的模版也是非常有用的。一个组件化的app,每一个视图都是一个组件: var myMod = angular.module('myMod',['ngRoute']);
myMod.component('home',{
template: '<h1>Home</h1><p>Hello,{{ $ctrl.user.name }} !</p>',controller: function() {
this.user = {name: 'world'};
}
});
myMod.config(function($routeProvider) {
$routeProvider.when('/',{
template: '<home></home>'
});
})
使用 var myMod = angular.module('myMod',bindings: {
user: '<'
}
});
myMod.config(function($routeProvider) {
$routeProvider.when('/',{
template: '<home user="$resolve.user"></home>',resolve: {
user: function($http) { return $http.get('...'); }
}
});
});
Component间的通信Directive需要其他Directive的controller来相互通信。在component中可以为require属性提供一个对象map来实现,map的key是所需controller构成的属性,而map的值是所需组件的名称。 不过要注意的是,所需的controller在它初始化完成之前是不可用的,但是可以确定的是当前controller在 下面的例子是将上一篇文章由Directive方式改为了component方式: docsTabsExample.html <!DOCTYPE html> <html> <head> <meta charset="uft-8"/> <title></title> </head> <script src="script/angular.min.js"></script> <body ng-app="docsTabsExample"> <my-tabs> <my-pane title="Hello"> <p>Lorem ipsum dolor sit amet</p> </my-pane> <my-pane title="World"> <em>Mauris elementum elementum enim at suscipit.</em> <p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p> </my-pane> </my-tabs> </body> <script> angular.module('docsTabsExample',[]) .component('myTabs',{ transclude: true,controller: ['$scope',function MyTabsController($scope) { var panes = this.panes = []; this.select = function (pane) { angular.forEach(panes,function (pane) { pane.selected = false; }); pane.selected = true; }; this.addPane = function (pane) { if (panes.length === 0) { this.select(pane); } panes.push(pane); }; }],templateUrl: 'my-tabs.html' }) .component('myPane',{ require: { tabsCtrl: '^myTabs' },transclude: true,bindings: { title: '@' },controller: function () { this.$onInit = function () { this.tabsCtrl.addPane(this); console.log(this); }; },templateUrl: 'my-pane.html' }); </script> </html>
my-tabs.html <div class="tabbable"> <ul class="nav nav-tabs"> <li ng-repeat="pane in $ctrl.panes" ng-class="{active:pane.selected}"> <a href="" ng-click="$ctrl.select(pane)">{{pane.title}}</a> </li> </ul> <div class="tab-content" ng-transclude></div> </div>
my-pane.html <div class="tab-pane" ng-show="$ctrl.selected"> <h4>{{title}}</h4> <div ng-transclude></div> </div>
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |