指令通过$ compile方法共享范围

时间:2013-07-08 18:54:36

标签: javascript angularjs

我在指令之间隔离范围时遇到了一些麻烦。我想这可能与我在$compile方法中定义的指令中使用$scope.addCategory方法的方式有关。

这是我的指示:

directive('siteCategory', [ function(){
        return{
            restrict: "E",
            replace: true,
            templateUrl: 'site-category.html',
            scope:{},
            controller: ['$scope', '$element', '$attrs', '$compile', function( $scope, $element, $attrs, $compile ){
                $scope.view = {};
                $scope.view.defaultCategoryName = "Name of Category";
                $scope.view.displayName = true;
                $scope.data = {};

                $scope.removeCategory = function(){
                    console.log('removing category', $element);
                    $element.remove();
                };
                $scope.addCategory = function(){
                    var newCategory = angular.element( document.createElement( 'site-category' ) );

                    console.log('adding category', $element);

                    angular.element( $element[0].querySelector('.category-name') ).after( newCategory );
                    $compile( $element )( $scope );
                    $scope.$apply();
                };

                $scope.updateCategoryName = function(){
                    console.log('editing category name', $element);
                    $scope.view.displayName = false;
                    $scope.$apply();
                    $element[0].querySelector('.category-name > input').focus();
                };

                $scope.saveCategoryName = function(){

                    $scope.data.categoryName = $scope.data.categoryName.trim();
                    console.log('saving category name: ', $scope.data.categoryName);

                    if( $scope.data.categoryName === "" ){
                        $scope.data.categoryName = $scope.view.defaultCategoryName;
                    }
                    $scope.view.displayName = true;
                    $scope.$apply();
                };

            }],

            link: function(scope, element, attrs){

                angular.element(element[0].querySelector('.remove')).bind( 'click', scope.removeCategory );
                angular.element(element[0].querySelector('.add')).bind( 'click', scope.addCategory );
                angular.element(element[0].querySelector('.display-name')).bind( 'click', scope.updateCategoryName );               
                angular.element(element[0].querySelector('.category-name input')).bind( 'blur', scope.saveCategoryName );

                // Default category name
                scope.data.categoryName = scope.view.defaultCategoryName;
            }
        };

    }]);

以下是该指令的模板:

<div class="category">
    <div class="actions">
        <span class="icon remove" data-icon="&#xe01e;"></span>
        <span class="icon add" data-icon="&#xe01d;"></span>
    </div>
    <div class="category-name">
        <span ng-show="view.displayName" class="display-name">{{data.categoryName}}</span>
        <input ng-hide="view.displayName" type='text' ng-model='data.categoryName' />
    </div>
</div>  

这是指令的程式化布局: directive layout

单击类别标题时,我将文本更改为输入框: enter image description here

当我向父类添加更多“子类别”时,问题开始上升。我单击父文本,输入框显示父元素和创建的第一个子类别: enter image description here

当子类别本身具有更多子类别时,会发生相同类型的行为: enter image description here

单击“添加”图标时,将创建相对于父项的新子类别。此操作发生在指令中的$scope.addCategory方法中。它会更改标记,以便在运行$ compile方法之前使用

<div class="category">
    <div class="actions">
        <span class="icon remove" data-icon="&#xe01e;"></span>
        <span class="icon add" data-icon="&#xe01d;"></span>
    </div>
    <div class="category-name">
        <span ng-show="view.displayName" class="display-name">{{data.categoryName}}</span>
        <input ng-hide="view.displayName" type='text' ng-model='data.categoryName' />
    </div>
    <site-category></site-category> <!-- new directive is created and will be compiled -->
</div>  

感谢那些已经做到这一点的人,所以似乎$scope.view对象和$scope.data对象上的范围在父子关系之间共享。希望每个指令都有一个孤立的范围。

这里找到的半风格代码的jsfiddle:http://jsfiddle.net/Tqxqb/1/

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

只需替换

 scope: {},

  

范围: '分离物',

这里是小提琴: http://jsfiddle.net/Tqxqb/2/