如何从指令的控制器调用链接函数中定义的范围方法

文森特

这是一个柱塞-我希望将“替换”替换为“替换”。

我的问题如下。我有两个指令myTabs和myPane在myTabs的link函数中,我向其隔离范围添加了一个方法setValue现在,我希望myPane能够设置值,因此我setValue在myTabs的控制器中添加了一个方法该方法基本上调用了示波器的方法。但是,由于控制器功能是在链接功能之前运行的,因此无法访问范围的方法。

有关完整的代码,请参阅Plunker,但以下是相关部分:

指令:

angular.module('docsTabsExample', [])
.directive('myTabs', function() {
  return {
    transclude: true,
    scope: {},
    controller: function($scope) {
      this.setValue = $scope.setValue;
    },
    link: function(scope, element, attrs){
      scope.value = 'To be replaced';
      scope.setValue = function(value){
        scope.value = value;
      };
    },
    templateUrl: 'my-tabs.html'
  };
})
.directive('myPane', function() {
  return {
    require: '^myTabs',
    transclude: true,
    scope: {
    },
    link: function(scope, element, attrs, tabsCtrl) {
      tabsCtrl.setValue('Replacement');
    }
  };
});

HTML:

<body ng-app="docsTabsExample">
<my-tabs>
<my-pane>
   One pane
</my-pane>
<my-pane title="World">
   Another pane
</my-pane>
</my-tabs>
</body>

运行,在控制台中可以看到Error: tabsCtrl.setValue is not a function

现在,只是为了确保我没有朝错误的方向前进,我应该描述我的实际问题。我正在写一个指令,requires ^ ngModel,具有嵌套指令。由于我只能在链接函数中访问ngModel的控制器,因此只能将setValue()方法添加到该函数的作用域中,但是我需要控制器将API暴露给嵌套指令,这就是我要这样做的原因this.setValue = $scope.setValue;

乔希

您确实只需要让指令控制器管理对$ scope的访问。

创建控制器时,它将具有与指令相同的作用域,因此您可以重新编写控制器代码,使其看起来像这样:

controller: function($scope) {

 //Snip...

 this.setValue = function(value){
   $scope.value = value;
 };
}

将逻辑转移到控制器后,您可以安全地从指令中删除范围函数。但是,您需要解决一个操作顺序问题。

默认情况下,alink: function(){}是一个Post Linking函数,它将在链接所有子指令之后执行您可以通过将逻辑移到“预链接”功能来解决此问题,因为该功能在链接子指令之前执行

link: {
  pre: function(scope, element, attrs){
   scope.value = 'To be replaced';
   //No need for function here
  }
}

现在,您的嵌套指令可以简单地在控制器上执行方法,这将依次在范围上设置适当的值。那里什么都不需要改变。

这是具有这些更改的Plunker:http ://plnkr.co/edit/ERf24t93rm1pmr8avyV1?p=preview

更新

好的,这是一个完整的示例,展示了如何ngModel在子指令中使用它来影响实际的绑定模型。您可以看到<input>绑定progressValue和实际自定义控件中的更改都已更新

如果您想自己玩这个游戏,这里有一个Plunker:http ://plnkr.co/edit/zdzm0l4THlCDTvdP4ne3?p=preview

(function() {

  var template = '<div>' +
    '<div ng-transclude></div>' +
    '<div class="progress">' +
    '<div class="progress-bar progress-bar-success progress-bar-striped"' +
    ' role="progressbar" aria-valuenow="0"' + 
    ' aria-valuemin="0" aria-valuemax="100">' +
    '<span></span>' +
    '</div>' +
    '</div>' +
    '</div>';

  function ParentWithModelDirective() {
    return {
      restrict: 'E',
      require: 'ngModel',
      template: template,
      transclude: true,
      replace: true,
      scope: {},
      link: {
        pre: function(scope, elem, attrs, ngModel) {
          var progressBar = elem.find('div').find('div'),
            label = progressBar.find('span');

          ngModel.$parsers.push(function(viewValue) {
            var numValue = 0;

            if (angular.isString(viewValue)) {
              viewValue = viewValue.replace('%', '');
            }

            numValue = parseInt(viewValue);

            return isNaN(numValue) ? 0 : numValue;
          });

          ngModel.$formatters.push(function(value) {
            return ngModel.$isEmpty(value) ? 'N/A' : value.toString() + '%';
          });

          ngModel.$render = function() {
            progressBar.css('width', ngModel.$viewValue);
            progressBar.attr('aria-valuenow', 
                             ngModel.$isEmpty(ngModel.$modelValue) ? 
                             0 : 
                             ngModel.$modelValue);
            label.text(ngModel.$viewValue);
          };
        }
      }
    };
  }

  function ChildOfParentDirective() {
    return {
      restrict: 'E',
      require: '^ngModel',
      template: "<button type='button' class='btn btn-success'>Complete</button>",
      scope: {},
      link: function(scope, elem, attrs, ngModel) {

        function listener() {
          ngModel.$setViewValue('100%', 'click');
          ngModel.$render();
        }

        elem.on('click', listener);
      }
    };
  }

  function AnotherChildOfParentDirective() {
    return {
      restrict: 'E',
      require: '^ngModel',
      template: "<button type='button' class='btn btn-warning'>Reset</button>",
      scope: {},
      link: function(scope, elem, attrs, ngModel) {
        function listener() {
          ngModel.$setViewValue('0%', 'click');
          ngModel.$render();
        }

        elem.on('click', listener);
      }
    };
  }

  angular.module('sample-app', [])
    .directive('parentWithModel', ParentWithModelDirective)
    .directive('childOfParent', ChildOfParentDirective)
    .directive('anotherChildOfParent', AnotherChildOfParentDirective)

}());
<script src="http://code.angularjs.org/1.3.0/angular.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" 
      rel="stylesheet" />
<div class="container" ng-app='sample-app' ng-init="progressValue = 30">
  <div class="masthead">
    <h3 class="text-muted">Sample App
        </h3>
  </div>
  <div class="row">
    <div class="col-sm-12">

      <div class="form-group">
        <label>Progress Value</label>
        <input type="text" class="form-control" ng-model="progressValue" />
      </div>

    </div>
  </div>
  <div class="row">
    <div class="col-sm-12">
      <parent-with-model ng-model="progressValue">
        <h1><code>progressValue = {{progressValue}}</code></h1>
        <child-of-parent></child-of-parent>
        <another-child-of-parent></another-child-of-parent>
        <br />
        <br />
      </parent-with-model>
    </div>
  </div>
  <!-- Site footer -->
  <div class="footer">
    <p>by <a href="http://www.technofattie.com">Techno Fattie</a>
    </p>
  </div>
</div>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从隔离范围指令中调用控制器方法?

来自分类Dev

在角度,如何调用指令控制器内定义的函数?

来自分类Dev

Angular JS:如何在Angular指令中从控制器的链接内部调用函数

来自分类Dev

Angular JS:如何在Angular指令中从控制器的链接内部调用函数

来自分类Dev

在javascript函数的指令中定义的控制器中调用方法

来自分类Dev

如何从外部控制器的指令中调用函数?

来自分类Dev

如何从控制器调用指令函数?

来自分类Dev

AngularJs指令链接函数无法更改在控制器范围内定义的变量

来自分类Dev

ng-click in指令未调用控制器范围内定义的函数

来自分类常见问题

从AngularJS中没有隔离范围的指令中调用控制器函数

来自分类Dev

AngularJS:将函数传递到指令的隔离范围以在其控制器中调用?

来自分类Dev

控制器代码运行后如何调用链接指令函数

来自分类Dev

如何从Rails 3中的链接调用控制器方法

来自分类Dev

控制器参数在我的指令链接函数中未定义

来自分类Dev

我的指令链接函数中未定义控制器参数

来自分类Dev

从指令中的链接调用控制器功能

来自分类Dev

如何将参数传递给控制器中定义但从Angularjs中的指令调用的方法?

来自分类Dev

从嵌套指令中调用控制器中的函数

来自分类Dev

如何从角度控制器调用自定义指令

来自分类Dev

如何将函数处理程序从控制器传递到AngularJs的指令隔离范围中?

来自分类Dev

如何将函数处理程序从控制器传递到AngularJs的指令隔离范围中?

来自分类Dev

AngularJS如何从控制器调用指令函数

来自分类Dev

从指令中调用Angular控制器函数

来自分类Dev

控制器中的Angular.js调用指令函数

来自分类Dev

AngularJS:从我的指令中调用控制器函数

来自分类Dev

从带有参数的指令中调用控制器函数

来自分类Dev

当我也使用指令控制器时,从指令中调用控制器方法。

来自分类Dev

从控制器调用angularjs指令函数

来自分类Dev

从控制器angularjs调用指令函数

Related 相关文章

  1. 1

    如何从隔离范围指令中调用控制器方法?

  2. 2

    在角度,如何调用指令控制器内定义的函数?

  3. 3

    Angular JS:如何在Angular指令中从控制器的链接内部调用函数

  4. 4

    Angular JS:如何在Angular指令中从控制器的链接内部调用函数

  5. 5

    在javascript函数的指令中定义的控制器中调用方法

  6. 6

    如何从外部控制器的指令中调用函数?

  7. 7

    如何从控制器调用指令函数?

  8. 8

    AngularJs指令链接函数无法更改在控制器范围内定义的变量

  9. 9

    ng-click in指令未调用控制器范围内定义的函数

  10. 10

    从AngularJS中没有隔离范围的指令中调用控制器函数

  11. 11

    AngularJS:将函数传递到指令的隔离范围以在其控制器中调用?

  12. 12

    控制器代码运行后如何调用链接指令函数

  13. 13

    如何从Rails 3中的链接调用控制器方法

  14. 14

    控制器参数在我的指令链接函数中未定义

  15. 15

    我的指令链接函数中未定义控制器参数

  16. 16

    从指令中的链接调用控制器功能

  17. 17

    如何将参数传递给控制器中定义但从Angularjs中的指令调用的方法?

  18. 18

    从嵌套指令中调用控制器中的函数

  19. 19

    如何从角度控制器调用自定义指令

  20. 20

    如何将函数处理程序从控制器传递到AngularJs的指令隔离范围中?

  21. 21

    如何将函数处理程序从控制器传递到AngularJs的指令隔离范围中?

  22. 22

    AngularJS如何从控制器调用指令函数

  23. 23

    从指令中调用Angular控制器函数

  24. 24

    控制器中的Angular.js调用指令函数

  25. 25

    AngularJS:从我的指令中调用控制器函数

  26. 26

    从带有参数的指令中调用控制器函数

  27. 27

    当我也使用指令控制器时,从指令中调用控制器方法。

  28. 28

    从控制器调用angularjs指令函数

  29. 29

    从控制器angularjs调用指令函数

热门标签

归档