Open hjzheng opened 9 years ago
知识点: scope设置
HTML
<body ng-app="test" class="container-fluid" ng-controller="AppController">
<ot-site>
<ot-list items="area.list" selected="area.current" transclude-to="site-header">
</ot-list>
</ot-site>
<ot-site>
<ot-list items="area.list" selected="area.current" transclude-to="site-menu">
</ot-list>
</ot-site>
<ot-site>
<ot-list items="app.list" selected="app.current" transclude-to="site-body">
</ot-list>
</ot-site>
</body>
JavaScript
angular.module('test', []).factory('MultiTransclude', () => {
return {
transclude: (iElm, transcludeFn) => {
transcludeFn((clone) => {
angular.forEach(clone, (cloneEl) => {
if(cloneEl.attributes) {
var tId = cloneEl.attributes["transclude-to"].value;
var target = iElm.find(`[transclude-id="${tId}"]`);
if(target.length) {
target.append(cloneEl);
} else {
cloneEl.remove();
throw new Error(`
Target not found, Please
specify the correct transclude-to Attribute
`);
}
}
});
});
}
};
})
.directive('otSite', ['MultiTransclude', (MultiTransclude) => {
// Runs during compile
return {
scope: {},
restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
template: `
<div class="container">
<header class="row header" transclude-id="site-header"></header>
<nav class="row menu" transclude-id="site-menu"></nav>
<main class="row body" transclude-id="site-body"></main>
<footer class="row footer"></footer>
</div>
`,
transclude: true,
link: function($scope, iElm, iAttrs, controller, transclude) {
MultiTransclude.transclude(iElm, transclude);
}
};
}])
.directive('otList', () => {
// Runs during compile
return {
scope: {
items: "=",
selected: "="
},
restrict: 'E',
template: `<ul class="nav nav-justified">
<li ng-repeat="item in items"
ng-class="{'active': item === selected}"
ng-click="selectItem(item)">
<a href="#" ng-bind="item"></a>
</li>
</ul>`,
replace: true,
link: ($scope, iElm, iAttrs, controller) => {
$scope.selectItem = function(item){
$scope.selected = item;
}
}
};
}).controller('AppController', ['$scope', ($scope) => {
$scope.area = {
list: [
"Configs",
"Services",
"Controllers",
"Directives"
],
current: 'Configs'
};
$scope.app = {
list: [
"Configs",
"Services",
"Controllers",
"Directives"
],
current: 'Configs'
};
}]);
知识: transclude设置为true会产生一个新的scope 关于transclude scope 和 隔离scope 的分析,抽时间在学习吧! html
<body ng-app="test" class="container-fluid" ng-controller="AppController">
<ot-site>
<ot-dropdown transclude-to="site-header">
<ot-trigger>
<button type="button" class="btn btn-link">{{app.current}}</button>
</ot-trigger>
<ot-target>
<ot-list items="app.list" selected="app.current" theme="list">
</ot-target>
</ot-dropdown>
<ot-list items="area.list" selected="area.current"
theme="nav" transclude-to="site-menu">
</ot-list>
</ot-site>
</body>
JavaScript
angular.module('test', []).factory('MultiTransclude', () => {
return {
transclude: (iElm, transcludeFn) => {
transcludeFn((clone) => {
angular.forEach(clone, (cloneEl) => {
if(cloneEl.attributes) {
var tId = cloneEl.attributes["transclude-to"].value;
var target = iElm.find(`[transclude-id="${tId}"]`);
if(target.length) {
target.append(cloneEl);
} else {
cloneEl.remove();
throw new Error(`
Target not found,
Please specify the correct transclude-to Attribute
`);
}
}
});
});
}
};
})
.directive('otSite', ['MultiTransclude', (MultiTransclude) => {
// Runs during compile
return {
scope: {},
restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
template: `
<div class="container">
<header class="row header" transclude-id="site-header"></header>
<nav class="row menu" transclude-id="site-menu"></nav>
<main class="row body" transclude-id="site-body"></main>
<footer class="row footer"></footer>
</div>
`,
transclude: true,
link: function($scope, iElm, iAttrs, controller, transclude) {
MultiTransclude.transclude(iElm, transclude);
}
};
}])
.directive('otList', () => {
// Runs during compile
return {
scope: {
items: "=",
selected: "=",
theme: "@"
},
restrict: 'E',
template: `<ul ng-class="{'nav nav-justified': theme === 'nav', 'list-group': theme === 'list'}">
<li ng-repeat="item in items"
ng-class="{'active': item === selected, 'list-group-item': theme === 'list'}"
ng-click="selectItem(item)">
<a href="#" ng-bind="item"></a>
</li>
</ul>`,
replace: true,
link: ($scope, iElm, iAttrs, controller) => {
$scope.selectItem = function(item){
$scope.selected = item;
}
}
};
}).directive('otDropdown', () => {
// Runs during compile
return {
scope: {},
restrict: 'E',
template: `<div ng-click="toggleTarget()" ng-transclude>
</div>`,
transclude: true,
controller: function($scope) {
this.targetOpen = false;
$scope.toggleTarget = () => {
this.targetOpen = !this.targetOpen;
}
}
};
}).directive('otTarget', () => {
// Runs during compile
return {
restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
require: '^otDropdown',
template: `
<div ng-transclude ng-show="ctrl.targetOpen"></div>
`,
transclude: true,
link: function($scope, iElm, iAttrs, ctrl) {
$scope.ctrl = ctrl;
}
};
})
.directive('otTrigger', () => {
// Runs during compile
return {
restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment
template: `
<div ng-transclude></div>
`,
transclude: true,
link: function($scope, iElm, iAttrs, controller) {
}
};
})
.controller('AppController', ['$scope', ($scope) => {
$scope.area = {
list: [
"Configs",
"Services",
"Controllers",
"Directives"
],
current: 'Configs'
};
$scope.app = {
list: [
"Configs",
"Services",
"Controllers",
"Directives"
],
current: 'Configs'
};
}]);
Reusable Components in Angular
视频: https://www.youtube.com/watch?v=dF_ObGgzGE8 Slides: https://docs.google.com/presentation/d/1ozBlL1MXxyYPSLzIaMtHO1YF-tHkEzKFsvt4s3rBBt0/pub#slide=id.g57f904f61_80
Multi-transclude Example
看这个例子前需要注意几个点
HTML
JavaScript