为 jQuery UI 按钮创建 AngularJS 指令 [英] Creating an AngularJS Directive for jQuery UI Button

查看:24
本文介绍了为 jQuery UI 按钮创建 AngularJS 指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:Fiddle w/完整解决方案:http://jsfiddle.net/langdonx/VXBHG/

<小时>

为了比较和对比 KnockoutJS 和 AngularJS,我浏览了 KnockoutJS 交互式教程,并在每个部分,我会使用我已经知道的一点点 + AngularJS 参考在 AngularJS 中重写它.>

当我进入创建自定义绑定教程的第 3 步时,我想现在是开始了解 Angular Directives 并编写自定义标签的好时机.然后我就惨败了.

我遇到了两个我无法弄清楚的问题.我创建了一个新的 Fiddle 来尝试了解正在发生的事情......

  • 1(fiddle):我想出了我的范围问题,但是,是否可以只通过 ng-click ?我让它工作的唯一方法是将它重命名为 jqb-click,这有点烦人.
  • 2(fiddle):我一申请.button() 到我的元素,事情变得很奇怪.我的猜测是因为 Angular 和 jQuery UI 都在操纵 HTML.我没想到会这样,但 Angular 似乎为我的 button 提供了自己的 span(参见 JavaScript 的第 21 行),当然 jQuery UI 也是如此,我期望的.我修改了 HTML 以使其看起来正确,但即使在此之前,这些功能都不起作用.我仍然有范围问题,并且没有模板绑定.我错过了什么?

我知道有一个 AngularUI 项目我应该看看,我可能可以只用 CSS 完成我想要做的事情,但在这一点上,更多的是学习如何使用指令而不是思考这个是个好主意.

解决方案

您可以通过设置 scope 参数在指令中创建一个独立的作用域,或者通过不设置它来让它使用父作用域.

由于您希望 ng-click 来自父作用域,因此此实例可能最容易在指令中使用父作用域:

一个技巧是在操作模板化指令中的 DOM 之前在指令中使用 $timeout ,以便在操作前给 DOM 时间重新绘制,否则元素似乎不存在于时间.

我使用了一个属性来传入文本,而不是担心嵌入编译.通过这种方式,当添加模板时表达式已经被编译,并且 link 回调提供了对属性的轻松访问.

<jqbutton ng-click="test(3)" text="{{title}} 3"></jqbutton>

angular.module('Components', []).directive('jqbutton', function ($timeout) {返回 {restrict: 'E',//表示该指令仅适用于 html 元素替换:真的,模板:'<按钮></按钮>',链接:函数(范围、元素、属性){//将按钮变成 jQuery 按钮$超时(函数(){/* 从自定义标签的属性设置文本*/element.text(attrs.text).button();}, 10);/* 非常轻微的延迟,即使使用0"也有效*/}};});

演示:http://jsfiddle.net/gWjXc/8/

指令非常强大,但也有一些学习曲线.同样在 angular 与淘汰赛的比较中,angular 更像是一个元框架,从长远来看,它比淘汰赛具有更大的灵活性

对于理解指令中的范围非常有帮助的阅读:

https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

Update: Fiddle w/ full solution: http://jsfiddle.net/langdonx/VXBHG/


In efforts to compare and contrast KnockoutJS and AngularJS, I ran through the KnockoutJS interactive tutorial, and after each section, I'd rewrite it in AngularJS using what little I already knew + the AngularJS reference.

When I got to step 3 of the Creating custom bindings tutorial, I figured it would be a good time to get spun up on Angular Directives and write a custom tag. Then I failed miserably.

I'm up against two issues that I haven't been able to figure out. I created a new Fiddle to try and wrap my head around what was going on...

  • 1 (fiddle): I figured out my scoping issue, but, is it possible to just passthrough ng-click? The only way I could get it to work is to rename it to jqb-click which is a little annoying.
  • 2 (fiddle): As soon as I applied .button() to my element, things went weird. My guess is because both Angular and jQuery UI are manipulating the HTML. I wouldn't expect this, but Angular seems to be providing its own span for my button (see line 21 of the JavaScript), and of course so is jQuery UI, which I would expect. I hacked up the HTML to get it looking right, but even before that, none of the functionality works. I still have the scope issue, and there's no template binding. What am I missing?

I understand that there's an AngularUI project I should be taking a look at and I can probably pull off what I'm trying to do with just CSS, but at this point it's more about learning how to use Directives rather than thinking this is a good idea.

解决方案

You can create an isolated scope in a directive by setting the scope parameter, or let it use the parent scope by not setting it.

Since you want the ng-click from parent scope it is likely easiest for this instance to use the parent scope within directive:

One trick is to use $timeout within a directive before maniplulatig the DOM within a templated directive to give the DOM time to repaint before the manipulation, otherwise it seems that the elements don't exist in time.

I used an attribute to pass the text in, rather than worrying about transclusion compiling. In this manner the expression will already have been compiled when the template is added and the link callback provides easy access to the attributes.

<jqbutton ng-click="test(3)" text="{{title}} 3"></jqbutton>

angular.module('Components', [])
    .directive('jqbutton', function ($timeout) {
    return {
        restrict: 'E', // says that this directive is only for html elements
        replace: true,        
        template: '<button></button>', 
        link: function (scope, element, attrs) {
            // turn the button into a jQuery button
            $timeout(function () {
                /* set text from attribute of custom tag*/
                element.text(attrs.text).button();
         }, 10);/* very slight delay, even using "0" works*/
        }
    };
});

Demo: http://jsfiddle.net/gWjXc/8/

Directives are very powerful, but also have a bit of a learning curve. Also in comparison of angular to knockout, angular is more of a meta framework that in the long run has far more flexibilty than knockout

Very helpful reading for understanding scope in directives:

https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

这篇关于为 jQuery UI 按钮创建 AngularJS 指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆