现在发现,当初的自己真的是太菜了,为什么你在指令中更改数据,没有作用呢?这其实是原型链的问题。

  详细的我就不在这里说了,有位大神早已发布了这个内容,在这里复制个地址给大家,有兴趣的可以看看

  http://www.angularjs.cn/A09C

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  忙活了一天终于写出了一个完整的angular指令,在后面的文章再来讲我制作的排序指令,由于还是菜鸟此文章仅仅用来借鉴,希望各位看到有不对的地方,希望能够指点一下。

  这里首先要讲的是angular在创建指令是经常会遇到的几个问题。

  1.作用域绑定策略

    这个其实不知道被讲了多少篇了,但是只有自己开始动手写才发现是很挺复杂的。这里只讲绑定策略,另外的scope:true和scope:false就跳过了

    第一个方法是“@”,这个的意思其实是绑定字符串,实际上是拿到该对象的值,并且是单向的 外部作用域可以影响内部作用域,但指令内部作用域却无法影响外部的作用域,在绑定的时候需要加上{{}} 代表引用scope作用域的值,没加上{{}}代表引用的是一个普通的字符串

    第二个方法是“=”,这个的意思是绑定对象,是双向的外部作用域可以影响内部作用域,但指令内部作用域也可以影响外部的作用域

     第三个方法是“&”,这个是用与controller和指令之间的交互的,控制器的方法可以绑定在这上面使用

    另外在html上如果出现用”-“的命名方法 则在js文件中需要”-“后面的第一个字母要大写,例如<hello-world></hello world> 则在js文件中需要用helloWorld命名

  2.在指令中使用ng内置指令

    这是非常常见的操作,但是类似ng-repeat,ng-switch等等指令是会创建自己的作用域的,这个时候你就需要注意作用域的问题了,这个作用域问题是挺致命的。

    下面写个例子给大家看看关于ng-repeat的问题

这个是一个手风琴效果,内容是来自于《用angularJS开发下一代Web应用的》,没读过的朋友建议买来看一下,还是有很大帮助的,效果就像bootstrap的手风琴,但是我要讲一些书上没有说的东西,大家可以将代码复制下来执行看看。

var myApp = angular.module('MyApp', []);
myApp.controller('myCtrl', ['$scope', function($scope){
$scope.isReverse = false;
$scope.menuItems = [{
title : "This first",
content : "This first content"  
},{
title : "This second",
content : "This second content"  
},{
title : "This third",
content : "This third content"  
}];
}]);
myApp.directive('accroding',function(){
return {
controller: function($scope, $element, $attrs, $transclude) {
var tabItems = [];
this.getOpen = function(selectedItem){
angular.forEach(tabItems, function(value, key){
if(value != selectedItem){
value.isOpen = false;
}
});
}
this.addItem = function(tabItem){
tabItems.push(tabItem);
} },
restrict: 'EA',
template: '<div ng-transclude></div>',
replace: true,
transclude: true,
link: function($scope, iElm, iAttrs, controller) { }
};
});
myApp.directive('expender', [function(){
return {
scope: {
title : '=expenderTitle',
isReverse : '=expenderIsreverse',
},
require: '^accroding',
restrict: 'EA',
template: '<div>'+
'<div ng-click="toggle()">{{title}} || isReverse:{{isReverse}}</div>'+
'<div ng-show="isOpen" ng-transclude></div>'+
'</div>',
replace: true,
transclude: true,
link: function($scope, iElm, iAttrs, controller) {
$scope.isOpen = false;
controller.addItem($scope);
$scope.toggle = function(){
$scope.isOpen = !$scope.isOpen;
controller.getOpen($scope);
$scope.isReverse = !$scope.isReverse;
}
}
};
}]);
<accroding>
<expender ng-repeat="item in menuItems" expender-title="item.title" expender-isreverse="order.isReverse">
{{item.content}}
</expender>
</accroding>
<br>
<div ng-repeat="item in menuItems">
{{item.content}} | {{item.title}} || {{isReverse}}
</div>

  没错,你发现了什么,你明明有绑定策略‘=’去绑定,但是你点击div触发toogle()的时候,却发现外部的isReverse没有发生改变,指令内部的isReverse却发生改变了。也就是说你并没有双向绑定,这是什么问题呢?让我们看看修改之后的例子

var myApp = angular.module('MyApp', []);
myApp.controller('myCtrl', ['$scope', function($scope){
$scope.order = {
isReverse : "false",
predicate : "2"
};
$scope.menuItems = [{
title : "This first",
content : "This first content"  
},{
title : "This second",
content : "This second content"  
},{
title : "This third",
content : "This third content"  
}];
}]);
myApp.directive('accroding',function(){
return {
controller: function($scope, $element, $attrs, $transclude) {
var tabItems = [];
this.getOpen = function(selectedItem){
angular.forEach(tabItems, function(value, key){
if(value != selectedItem){
value.isOpen = false;
}
});
}
this.addItem = function(tabItem){
tabItems.push(tabItem);
} },
restrict: 'EA',
template: '<div ng-transclude></div>',
replace: true,
transclude: true,
link: function($scope, iElm, iAttrs, controller) { }
};
});
myApp.directive('expender', [function(){
// Runs during compile
return {
scope: {
title : '=expenderTitle',
isReverse : '=expenderIsreverse',
predicate : '=expenderPredicate',
},
require: '^accroding',
restrict: 'EA',
template: '<div>'+
'<div ng-click="toggle()">{{title}} {{isReverse}} {{predicate}}</div>'+
'<div ng-show="isOpen" ng-transclude></div>'+
'</div>',
replace: true,
transclude: true,
link: function($scope, iElm, iAttrs, controller) {
$scope.isOpen = false;
controller.addItem($scope);
$scope.toggle = function(){
$scope.isOpen = !$scope.isOpen;
controller.getOpen($scope);
$scope.isReverse = !$scope.isReverse;
$scope.predicate = "22";
}
}
};
}]);
<accroding>
<expender ng-repeat="item in menuItems" expender-title="item.title" expender-isreverse="order.isReverse" expender-predicate="order.predicate">
{{item.content}}
</expender>
</accroding>
<div ng-repeat="item in menuItems">
{{item.content}} | {{item.title}} || {{order.isReverse}} || {{order.predicate}}
</div>

  把isReverse写成了对象的形式发现可以相互作用了,这就是ngRepeat的问题,ngRepeat创建了一个新的作用域,如果我们用基本数据类型去绑定的话,是无法成功的,需要将数据编程对象的形式去绑定,这样在指令内部改变值之后才可以与外部的作用域绑定,另外尽量在指令中不去使用ng-if,因为ng-if是根据节点决定添加和删除的节点的,当一个元素被ng-if从DOM中删除时,与其关联的作用域也会被销毁。而且当它重新加入DOM中时,则会生成一个新的作用域,而ng-show和ng-hide则不会。

angularJS在创建指令需要注意的问题(指令中使用ngRepeat)的更多相关文章

  1. 带你走近AngularJS 之创建自定义指令

    带你走近AngularJS 之创建自定义指令 为什么使用AngularJS 指令? 使用过 AngularJS 的朋友应该最感兴趣的是它的指令.现今市场上的前端框架也只有AngularJS 拥有自定义 ...

  2. AngularJS高级程序设计读书笔记 -- 指令篇 之 内置指令

    1. 内置指令(10-12 章) AngularJS 内置超过 50 个内置指令, 包括 数据绑定,表单验证,模板生成,时间处理 和 HTML 操作. 指令暴露了 AngularJS 的核心功能, 如 ...

  3. AngularJS之一个元素上绑定多个指令作用域

    前言 众所周知,我们在自定义指令时,会指定它的作用域,即scope设置项(默认值为false). 且,scope设置项,可以有三种值,从而也就代表三种不同的作用域,下面我们再来一起回顾下: 指令之sc ...

  4. vue指令详解和自定义指令

    在vue中,指令以v-开头,是一种特殊的自定义行间属性,指令的职责就是其表达式的值改变时相应地将某些行为应用到DOM上 指令使用的示例 在下面的运行结果中可以看到,v-html是可以解析html标签的 ...

  5. angular学习笔记(三十)-指令(9)-一个简单的指令示例

    学了前面这么多关于指令的知识,现在就用指令来写一个小组件:expander 这个组件的功能就是点击开展菜单,再点击收起菜单: ↑↓点击展开收起 下面来看它的代码: html: <!DOCTYPE ...

  6. JSP基本的语法、3个编译指令、7个动作指令、9个内置对象

    一.jsp概述 JSP是java server page的缩写,其本质是一个简化的servlet,是一种动态网页技术标准.jsp页面是在HTML页面中嵌入java程序段.使用jsp开发的应用程序能够跨 ...

  7. Vue框架(二)——Vue指令(v-once指令、v-cloak指令、条件指令、v-pre指令、循环指令)、todolist案例、Vue实例(计算、监听)、组件、组件数据交互

    Vue指令 1.v-once指令  单独使用,限制的标签内容一旦赋值,便不可被动更改(如果是输入框,可以主动修改) <!DOCTYPE html> <html lang=" ...

  8. Docs-.NET-C#-指南-语言参考-预处理器指令:C# 预处理器指令

    ylbtech-Docs-.NET-C#-指南-语言参考-预处理器指令:C# 预处理器指令 1.返回顶部 1. C# 预处理器指令 2015/07/20 本节介绍了以下 C# 预处理器指令: #if ...

  9. 创建一个目录info,并在目录中创建一个文件test.txt,把该文件的信息读取出来,并显示出来

    /*4.创建一个目录info,并在目录中创建一个文件test.txt,把该文件的信息读取出来,并显示出来*/ #import <Foundation/Foundation.h>#defin ...

  10. Java内存模型一个经典例子-指令重排序与CPU指令多发射导致执行结果异常

    先上代码: import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; ...

随机推荐

  1. Cross compile openwrt

    在Centos7上交叉编译生成OpenWrt固件 安装ss-* 获取最新的ss, 当前是 wget https://github.com/shadowsocks/shadowsocks-libev/a ...

  2. 浅谈h5移动端页面的适配问题

    一.前言 昨天唠叨了哈没用的,今天说点有用的把.先说一下响应式布局吧,我一直认为响应式布局的分项目,一下布局简单得项目做响应式还是可以可以得.例如博客.后台管理系统等.但是有些会认为响应式很牛逼,尤其 ...

  3. leetcode387

    Given a string, find the first non-repeating character in it and return it's index. If it doesn't ex ...

  4. Q promise API简单翻译

    详细API:https://github.com/kriskowal/q/wiki/API-Reference Q提供了promise的一种实现方式,现在在node中用的已经比较多了.因为没有中文的a ...

  5. 《JS权威指南学习总结--1.2客户端JS》

    1.2客户端JS --本节讲述客户端JS部分各章节的讲述内容 一.第十三章讲述JS代码通过<script>标签来嵌入到HTML文件中. 二.第十四章讲解WEB浏览器脚本技术,并涵盖客户端J ...

  6. 模拟post请求-->测试api是否可用-->再交给ios开发

    提交给iso开发前.先模拟post提交,测试返回是否正确 =============post.php文件 ios每次最少要提交5个数据, 加密串 seqno , 请求验证码 source, 设备唯一标 ...

  7. A计划

    A计划 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submissio ...

  8. 更改 android realtek的系统权限

    由于在 在删除系统的文件时候出现 Read-only file system,所以要获取权限. 推出shell adb mount mount -o rw,remount /system 就可以了

  9. 大学二三事——那些人(1)

    校歌墙的对面是一座历史比较悠久的建筑,以前叫做12号楼,后来改成了"诚"字楼. 在诚字楼一楼昏暗的走廊上,你总是能看见一位大概四五十岁的大叔,有时他会指着挂在墙上的学校简介,一个人 ...

  10. http的状态码(中英文)

    1**:请求收到,继续处理 2**:操作成功收到,分析.接受 3**:完成此请求必须进一步处理 4**:请求包含一个错误语法或不能完成 5**:服务器执行一个完全有效请求失败 100——客户必须继续发 ...