使用指令创建自定义属性的Angular JS

使用指令创建自定义属性的Angular JS

介绍

Angular 是一个相当的new javascript库,它为web界面开发提供了。 这让你可以使用MVVM设计模式来开发一个网页界面。 本文的第一次迭代没有花时间来解释 Angular 点或者MVVM设计 Pattern的核心。 Angularjs.org 可以让你开始。 我还没有决定是否要对 Angular的功能进行完整描述,以供介绍或者不使用。 我还没有决定是否将这篇文章的那部分内容写出来,或者写一篇单独的文章作为本文。

出于本文的目的,我使用 Angular 特定术语"指令interchangeably自定义属性的概念。"

背景

我在web开发中做了大量的工作,并且使用了 Angular 中的MVVM设计,我特别兴奋地签出了。 我对它所做的一些事情非常满意。 我已经开始探索 Angular 和功能的特性,但是我对 Angular 赋予定制属性的能力尤其深刻,因为它使得标记成为一种方式,使javascript保持简单。

项目说明

本文并不打算全面说明如何使用 Angular 。 不幸的是,我觉得当前的文档可以在 http://www.angularjs.org 不可能是彻底的,但它确实可以让你开始。 也就是说,我将为我上传的示例项目提供一些简短的想法/解释。

demo.js: 这是我们的视图模型或者控制器的javascript文件。 请注意,相同的视图模型可能会导致不同的行为,因为标记的驱动。 这是一个相当简单的示例,带有项目。标题和指向活动项的指针。 如果你正确地执行 Angular,你的ViewModel将完全不知道 UI 。 Dom操作。标记创建等不应该在你的视图中。

指令: 你的自定义属性应该尽可能以通用方式进行。 它们是DOM和HTML相关工作的适当地方,它们应该不知道任何视图,以使这些属性完全模块化和可以重用。 本文将重点介绍 directives.js,,以便稍后在本文中进一步讨论。

的html文件: 为了清晰起见,我使用了一些约定。 任何以"ng -"开头的属性都表示它是调用 Angular 功能的属性,这是 Angular 本身使用的约定。 为了防止与现有或者将来的Angular 属性发生任何冲突,我选择使用"ng-ds -"启动任何自定义指令。 我将所有的指令或者属性驱动行为放在文件 Directives.js. 中,这样可以构建一个单独的属性库,这些属性可以在一个非常模块化和强大的方式。

:一个例子使用了jquery模式。 除这里之外,我在指令中使用了基本的jquery 。 使用你偏好的任何其他模式是微不足道的。 你可以发现在你的ViewModel中使用jquery进行ajax调用,但这实际上不是 neccesary,因为 Angular 提供了自己的一些ajax实用程序。 ( 这超出了本文的范围。) 注意,你可以轻松地使用 Angular 而不用 jquery 。

创建属性/指令

Directives.js 必须在 angular.js 之后包含。 这样就可以声明自己的Angular 模块。


var dsApp = angular.module('dsApp', []); 





我没有挖掘太多的内容,但是第一个属性是与你分配给ng-app属性的值匹配的名称。 第二个是依赖项( 除了本文的范围之外,还有一些我还没有研究过的东西)的数组。 变量名称显然不必与属性中的名称匹配。

创建模块之后,就可以在模块上声明每个指令。 这些指令将成为 Angular 将处理和连接的属性。 让我们看看第一个指令。


dsApp.directive('ngDsFade', function () {


 return function (scope, element, attrs) {


 element.css('display', 'none');


 scope.$watch(attrs.ngDsFade, function (value) {


 if (value) {


 element.fadeIn(200);


 } else {


 element.fadeOut(100);


 }


 });


 }


}); 





这里指令将设置一个元素,当属性中计算的值为 true 时,该元素将淡入,并在属性为 false 时将它的淡出。 因此,你应该看到ng-ds-fade在html中使用了几个示例。

第一个参数定义属性。 这里的参数名应该是 camel-cased 。 然后 Angular 将它的转换为dash-separated小写属性。 因此 ngDsFade => ng-ds-fade作为你可以使用的属性。 第二个参数是函数,它返回 Angular 用来连接属性行为的代码。 返回的函数评估的是 viewmodel ( 作用域),带有属性( 元素)的dom节点,以及这个模块具有( attrs )的其他属性。

你可以做的第一件事是设置一些初始化。 在这种情况下,我们隐藏元素来初始化。 值得注意的是,在代码的这一点上,属性出现在dom元素上的顺序非常重要。 任何出现在问题中的属性( 。ng-ds-fade中的) 都不会出现在attrs中。 因此,如果你需要使用多个属性,那么如果你在设置大多数时间的观察者之外进行的事情,那么你的订单就变得。 当表被评估时,所有的属性都存在。 所以大多数时候这不是问题。 我不希望创建那些属性的顺序成为功能要求的东西。 这显然会导致代码不容易维护或者模块化。

范围$watch是电源出现的地方。 这样,只要属性中的值发生更改,Angular 就可以对函数进行评估。 在这种情况下,true 或者not-null值将淡入,并且使用jquery的淡入淡出将淡出 false 或者null值。

示例中另一个同样简单的指令/属性是 ng-ds-active 。 它只是根据绑定到属性的值在元素上添加或者移除活动类。 这是另一个简单但非常有用的属性,你可以在。

模态指令

让我们来看看一个更有趣的。 如何在模态中打开或者关闭带有dom元素内容的模式。 因此,只要将属性 ng-ds-modal="编辑"放在你的标记( 其中EditMode是你的ViewModel上的一个布尔值) 中,就可以通过简单地更改你的视图上的EditMode的值。 有趣的是,你可以在属性的值中执行一些基本的布尔语法,而观察者可以很好地处理它。 例如在模式示例html中,我们设置 ng-ds-modal="activeitem =null"。 现在让我们来看看这个指令的javascript 。


dsApp.directive('ngDsModal', function () {


 return function (scope, element, attrs) {


 var diag = $(element).dialog(


 {autoOpen:false,


 close:function()


 {


 try


 {


 var functionName= attrs.ngDsModalClosed;


 //alert(functionName);


 if(typeof scope[functionName]=="function")


 setTimeout(function(){scope.$apply(scope[functionName]);},100);


 }


 catch(err)


 {}


 }


 });


 scope.$watch(attrs.ngDsModal, function (value) {


 if (value) {


 $(element).dialog("open");


 } 


 else 


 {


 $(element).dialog("close");



 }


 });


 }


}); 





这里的初始化代码从传入的dom节点设置一个jquery对话框。 作为其中的一部分,我们设置了close事件处理程序。 当函数求值时,attrs对象拥有所有属性,因此属性顺序不重要。 请注意,close函数查找函数名。 如果我们在作用域上定义了一个函数,那么我们就调用它。 这里需要两个技巧。

1.为了执行 Angular re-evaluating绑定值所执行的函数,需要使用作用域 $apply 。 如果你不通过范围调用,那么对你的ViewModel的任何更改都不会导致对DOM等的绑定更新反映。

2.我发现在这里需要( 通过谷歌搜索)的硬方式,以防止 Angular 出错。 关于摘要的一些东西已经在进行中或者类似于。 我不记得具体的细节,也不明白为什么我们会得到错误。

因此我们需要关闭模式处理程序,因为可以通过关闭jquery按钮关闭jquery模式,因为它没有以任何方式绑定到我们的viewmodels 。 换句话说,我们希望有一种关闭jquery模式的方法来通知ViewModel它已经关闭了,所以ViewModel可以更新它应该更新的任何属性。

我们用一个处理ActiveItem指针的处理程序来设置 ViewModel 。 注意我们如何使用第二个属性( ng-ds-modal-closed ) 定义在关闭模式时调用什么。 这使得我们可以对任何ViewModel使用相同的指令,甚至可以针对一个视图中不同元素的多个属性使用。

内联编辑指令

好的,如果我解释得足够好,让你把你的头环绕起来,那么我们可以转移到一个更重要,更重要的地方。 我想要一个让我们定义一个用于内联编辑的模板。 为了做到这一点,我们设置了三个属性,在几个地方使用。

内联模板

通过将这个属性放在模板标记( 我们在另一个例子中的模式) 上,我们调用了该元素上的一些初始化。 这里属性不需要任何观察器,因此它只设置一些非常简单的初始化。 让我们来看看。


 dsApp.directive('ngDsInlineTemplate',function(){


 return function(scope,element,attrs)


 {


 var templateElement = $(element);


 var name= templateElement.attr("ng-ds-inline-template");


 $(element).hide();//hide our template.


 scope[name]=element;//save a pointer to the template node in the 



 }


}); 





我们首先获取元素并保存它的名称。 我没有在attrs数组中找到这个值,但是可以通过简单检查模板上的属性获得它。 我们隐藏模板,然后将一个属性保存在ViewModel上。 这使得我们可以在一个单独的ViewModel上使用多个内联编辑模板,如果我们需要。 因此这个属性和指令的目的只是给我们一个指向模板的指针。 它保存在范围上,但是实际上,ViewModel永远不会消耗它。 我们在另一个指令中使用它。

InlineEdit和 TemplateName

ng-ds-template-name设置ds-inline-edit查找在我们的模板中使用的dom元素的名称。


dsApp.directive('ngDsInlineEdit',function()


{


 return function(scope,element,attrs)


 {


 //$(element).hide();//hide our template.


 scope.$watch(attrs.ngDsInlineEdit,function(value)


 {


 //we need to get our template element to move it and show, or just hide it.


 if(!attrs.ngDsTemplateName)


 return;//we don't have a template yet.


 var template = $(scope[attrs.ngDsTemplateName]);


 if(value)


 {


 setTimeout(function(){


 //move the template here and show it.


 $(element).after(template);


 template.fadeIn(200);


 },10);


 }


 else


 {


 template.hide();


 }



 });



 }


});





这个人从模态示例中感觉到。 我们决定基于项目放置模板的位置。 在模态中,我们将与观察者有关的属性放在模态的内容上。 在本例中,我们放置了在特定项目上放置和显示模板的条件。 因此,当它是特定项的true 时,模板将立即放置在该元素之后。 等待实际上是正确处理切换活动项必需的。 否则,我们可以在移动它时得到计时问题,然后隐藏完成和内联编辑不可见。 当 false 被隐藏时。

因此,对于这一组指令,你具有以下属性:
ng-ds-inline-template='somename': 放置在你的内联编辑模板的dom节点上。
ng-ds-template-name='somename': 放置在任何要将该模板移动到编辑模式时都要移动的项目上。

ng-ds-inline-edit = 条件: 当评估为 true 时,该条件会在你放置这里属性的项之后立即显示该模板。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值