Creating an AngularJS Directive for jQuery UI Button

心不动则不痛 提交于 2019-12-09 13:48:19

问题


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.


回答1:


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



来源:https://stackoverflow.com/questions/15603005/creating-an-angularjs-directive-for-jquery-ui-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!