2013-11-26 121 views
10

这不应该太难,但我不知道如何做到最好。AngularJS - 从子指令访问父指令属性

我有一个父指示,例如:

directive('editableFieldset', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     model: '=' 
    }, 
    replace: true, 
    transclude: true, 

    template: ' 
     <div class="editable-fieldset" ng-click="edit()"> 
     <div ng-transclude></div> 

     ... 

     </div>', 

    controller: ['$scope', function ($scope) { 
     $scope.edit = -> 
     $scope.editing = true 

     // ... 
    ] 
    }; 
}); 

和一个小孩指令:

.directive('editableString', function() { 
    return { 
    restrict: 'E', 
    replace: true, 

    template: function (element, attrs) { 
     '<div> 
     <label>' + attrs.label + '</label> 
     <p>{{ model.' + attrs.field + ' }}</p> 

     ... 
     </div>' 
    }, 
    require: '^editableFieldset' 
    }; 
}); 

我怎么能轻易地从孩子的指令访问父指令的modelediting性质?在我的链接功能中,我可以访问父范围 - 我应该使用$watch来观看这些属性吗?

放在一起,我想拥有的是:

<editable-fieldset model="myModel"> 
    <editable-string label="Some Property" field="property"></editable-string> 
    <editable-string label="Some Property" field="property"></editable-string> 
</editable-fieldset> 

的想法是有一组默认显示的字段。如果点击它们,它们就成为输入并且可以被编辑。

+0

你能举一个最终标记的样子吗? –

+0

我已经在现在 –

回答

8

this SO post获取灵感,我有一个工作解决方案here in this plunker。我不得不改变很多。我选择在editableString上也有一个独立的作用域,因为它更容易将正确的值绑定到模板。否则,您将不得不使用compile或其他方法(如$transclude服务)。

下面是结果:

JS:

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

myApp.controller('Ctrl', function($scope) { 

    $scope.myModel = { property1: 'hello1', property2: 'hello2' } 

}); 


myApp.directive('editableFieldset', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     model: '=' 
    }, 
    transclude: true, 
    replace: true, 
    template: '<div class="editable-fieldset" ng-click="edit()"><div ng-transclude></div></div>', 
    link: function(scope, element) { 
     scope.edit = function() { 

     scope.editing = true; 
     } 
    }, 
    controller: ['$scope', function($scope) { 

     this.getModel = function() { 
     return $scope.model; 
     } 

    }] 
    }; 
}); 

myApp.directive('editableString', function() { 
    return { 
    restrict: 'E', 
    replace: true, 
    scope: { 
     label: '@', 
     field: '@' 
    }, 
    template: '<div><label>{{ label }}</label><p>{{ model[field] }}</p></div>', 
    require: '^editableFieldset', 
    link: function(scope, element, attrs, ctrl) { 

     scope.model = ctrl.getModel(); 
    } 
    }; 
}); 

HTML:

<body ng-controller="Ctrl"> 
    <h1>Hello Plunker!</h1> 
    <editable-fieldset model="myModel"> 
     <editable-string label="Some Property1:" field="property1"></editable-string> 
     <editable-string label="Some Property2:" field="property2"></editable-string> 
    </editable-fieldset> 
    </body> 
+0

谢谢。这并不能真正帮助访问动态属性,例如'编辑'。我想我将不得不使用'$ watch'来跟踪我的孩子指令中的那个? –

+0

此外,我会认为像这里常量,不变的属性,如'field'和'label',将它们传递给生成模板的函数会比将它们添加为绑定更快?没有必要浪费时间在每个摘要周期检查那些不会改变的绑定,对吧? –

+0

不在编辑孩子的属性吗?或者你想一次只编辑一个孩子吗? –

7

您可以通过孩子向链路功能传递属性可以访问父控制器

link: function (scope, element, attrs, parentCtrl) { 
    parentCtrl.$scope.editing = true; 
} 
+3

如果你得到这个第四个参数: ... 要求:“^ parentCtrl” – Leonardo

+1

是的,这个概念在指令文档[**](https)中的“**创建指令**” ://docs.angularjs.org/guide/directive) – Harish