AngularJS - 从子指令访问父指令属性 [英] AngularJS - accessing parent directive properties from child directives

查看:32
本文介绍了AngularJS - 从子指令访问父指令属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这应该不是一件很难的事情,但我不知道如何最好地做到这一点.

我有一个父指令,如下所示:

directive('editableFieldset', function () {返回 {限制:'E',范围: {型号:'='},替换:真的,转置:真实,模板: '<div class="editable-fieldset" ng-click="edit()"><div ng-transclude></div>...

',控制器:['$scope',函数($scope){$scope.edit = ->$scope.editing = true//...]};});

还有一个子指令:

.directive('editableString', function () {返回 {限制:'E',替换:真的,模板:函数(元素,属性){'

<标签>'+ attrs.label + '</label><p>{{ 模型.+ attrs.field + ' }}</p>...

'},要求:'^editableFieldset'};});

如何从子指令轻松访问父指令的 modelediting 属性?在我的链接函数中,我可以访问父作用域 - 我应该使用 $watch 来查看这些属性吗?

总而言之,我想要的是:

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

这个想法是默认显示一组字段.如果点击,它们将成为输入并且可以编辑.

解决方案

这篇 SO 帖子中汲取灵感,我这里有一个可行的解决方案.

我不得不改变很多.我也选择在 editableString 上设置一个独立的作用域,因为这样更容易将正确的值绑定到模板.否则,您将不得不使用 compile 或其他方法(如 $transclude 服务).

结果如下:

JS:

var myApp = angular.module('myApp', []);myApp.controller('Ctrl', function($scope) {$scope.myModel = { property1: 'hello1', property2: 'hello2' }});myApp.directive('editableFieldset', function () {返回 {限制:'E',范围: {型号:'='},转置:真实,替换:真的,模板:'<div class="editable-fieldset" ng-click="edit()"><div ng-transclude></div></div>',链接:函数(范围,元素){scope.edit = function() {scope.editing = true;}},控制器:['$scope',函数($scope){this.getModel = function() {返回 $scope.model;}}]};});myApp.directive('editableString', function () {返回 {限制:'E',替换:真的,范围: {标签: '@',场地: '@'},模板:'<div><label>{{label}}</label><p>{{model[field]}}</p></div>',要求:'^editableFieldset',链接:函数(范围,元素,属性,ctrl){scope.model = ctrl.getModel();}};});

HTML:

 <h1>你好,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>

This should not be too hard a thing to do but I cannot figure out how best to do it.

I have a parent directive, like so:

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

       // ...
    ]
  };
});

And a child directive:

.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'
  };
});

How can I easily access the model and editing properties of the parent directive from the child directive? In my link function I have access to the parent scope - should I use $watch to watch these properties?

Put together, what I'd like to have is:

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

The idea is to have a set of fields displayed by default. If clicked on, they become inputs and can be edited.

解决方案

Taking inspiration from this SO post, I've got a working solution here in this plunker.

I had to change quite a bit. I opted to have an isolated scope on the editableString as well because it was easier to bind in the correct values to the template. Otherwise, you are going to have to use compile or another method (like $transclude service).

Here is the result:

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>

这篇关于AngularJS - 从子指令访问父指令属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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