AngularJS:怎么说一个指令来克隆作用域? [英] AngularJS : How to say to a directive to clone scope?

查看:56
本文介绍了AngularJS:怎么说一个指令来克隆作用域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个小提琴,并且无法完成这项工作.我相信原因在于这两个li元素具有自定义指令就地共享范围.解决方案是对指令说,创建在父级上绑定的范围的副本-可以包含帮助吗?

I have this fiddle, and can not make this work. I believe that the reason resides in that two li elements with a custom directive edit-in-place share scope. The solution would be to say to the directive to create a copy of the scope that binds on the parent - can transclude help?

angular.module('bla', [])
    .directive('editInPlace', ['$parse','$compile', function($parse, $compile) {
    return {
        restrict: 'A',
        scope: true,
        link: function (scope, element, attribs) {
            var inputStart = '<input style="border: 2 solid black" name="inPlaceInput" style="display:none" value="';
            var inputEnd = '">';

            scope.editModeAccessor = $parse(attribs.editInPlace);
            scope.modelAccessor = $parse(attribs.ngBind);

            scope.$watch(attribs.editInPlace, function(newValue, oldValue){
                if (newValue){
                    console.debug("click");
                    console.debug("value: " + scope.modelAccessor(scope));
                    var inputHtml = inputStart + scope.modelAccessor(scope) + inputEnd;
                    element.after(inputHtml);
                    jQuery(element).hide();
                    scope.inputElement = jQuery("input[name=inPlaceInput]");
                    scope.inputElement.show();
                    scope.inputElement.focus();
                    scope.inputElement.bind("blur", function() {
                        blur();
                    });
                } else {
                    blur();
                }
            });

            function blur(){
                console.debug("blur secondary");
                if (scope.inputElement){
                    console.debug("blur secondary inputElement found");
                    var value = scope.inputElement.val();
                    console.debug("input value: "+ value);
                    scope.inputElement.remove();
                    jQuery(element).show();
                    scope.editModeAccessor.assign(scope, false);
                    scope.modelAccessor.assign(scope, value);
                }
            }
        }
    }
                            }]);

function ContactsCtrl($scope, $timeout){
    $scope.contacts = [{number:'+25480989333', name:'sharon'},{number:'+42079872232', name:''}];
    $scope.editMode = false;
    var editedId;
    $scope.edit = function(id){
        $scope.editMode = true;
        jQuery("#"+id).hide();
        editedId = id;
        //TODO show delete button
    }
    $scope.$watch('editMode', function(newValue, oldValue){
        if (!newValue && editedId){
            jQuery("#"+editedId).show();
        }
    });
}


<div ng-app="bla">
<div ng-controller="ContactsCtrl">
<h4>Contacts</h4>
<ul>
    <li ng-repeat="contact in contacts">
        <span edit-in-place="editMode" ng-bind="contact.number"></span>
        <span edit-in-place="editMode" ng-bind="contact.name"></span>
        <span id="{{$index}}" ng-click="edit($index)"><i class="icon-edit">CLICKtoEDIT</i></span>
    </li>
</ul>
</div></div>

推荐答案

我认为克隆范围不是最佳解决方案.

I think cloning the scope is not the best solution.

在使用angular创建指令时,应将 all 功能封装在指令中.您还应该避免在不需要时混用jQuery.在大多数情况下(如本例所示),您只是在引入不必要的复杂性.最后,类是控制显示的最佳方法,而不是元素上的 style 属性.

When creating a directive in angular, you should encapsulate all the functionality within the directive. You should also avoid mixing jQuery in when you don't have to. Most of the time (as in this case) you're just introducing unnecessary complexity. Lastly, classes are the best way of controlling display, rather than the style attribute on an element.

我采取了一种更加有角度的"方式重写您的指令的自由-没有jQuery.从更新的 jsFiddle 中可以看到,它更简单,更干净.另外,它也有效!

I took the liberty of rewriting your directive in a more "angular" way - with no jQuery. As you can see from the updated jsFiddle, it is simpler and cleaner. Also, it works!

可以很容易地修改此指令,以添加许多其他令人敬畏的功能.

This directive can be easily modified to add lots of additional awesome functionality.

app.directive( 'editInPlace', function() {
  return {
    restrict: 'E',
    scope: { value: '=' },
    template: '<span ng-click="edit()" ng-bind="value"></span><input ng-model="value"></input>',
    link: function ( $scope, element, attrs ) {
      // Let's get a reference to the input element, as we'll want to reference it.
      var inputElement = angular.element( element.children()[1] );

      // This directive should have a set class so we can style it.
      element.addClass( 'edit-in-place' );

      // Initially, we're not editing.
      $scope.editing = false;

      // ng-click handler to activate edit-in-place
      $scope.edit = function () {
        $scope.editing = true;

        // We control display through a class on the directive itself. See the CSS.
        element.addClass( 'active' );

        // And we must focus the element. 
        // `angular.element()` provides a chainable array, like jQuery so to access a native DOM function, 
        // we have to reference the first element in the array.
        inputElement[0].focus();
      };

      // When we leave the input, we're done editing.
      inputElement.prop( 'onblur', function() {
        $scope.editing = false;
        element.removeClass( 'active' );
      });
   }
};

});

这篇关于AngularJS:怎么说一个指令来克隆作用域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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