2013-11-26 125 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