javascript 无法从指令访问控制器范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14022446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 20:30:51  来源:igfitidea点击:

Can't access controller scope from directive

javascriptangularjs

提问by Yair Nevet

This is my app config:

这是我的应用程序配置:

angular.module('myApp', ['myApp.directives', 'myApp.controllers', 'myApp.services']);

This is my controller:

这是我的控制器:

angular.module('myApp.controllers', [])
  .controller('MainCtrl', function ($scope) {
      $scope.name = 'world';
  });

This is my directive:

这是我的指令:

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

directives.directive("hello", function () {
    return function (scope, elm, attrs) {
        elm.text("hello, " + scope[attrs.name]);
    };
});

and this is my html:

这是我的 html:

<div ng-controller="MainCtrl">
    <h1 hello></h1>
</div>

The is problem is that angular render the directive as:

问题是 angular 将指令渲染为:

hello, undefined

你好,未定义

Instead of:

代替:

hello, world

你好世界

What is wrong?

怎么了?

采纳答案by Liviu T.

You are accessing scope[attrs.name]but the directive doesn't provide a value for the attribute name

您正在访问scope[attrs.name]但该指令未提供该属性的值name

There are 2 options:

有2个选项:

  1. Change the directive to elm.text("hello, " + scope['name']);This is not a preferred way as it hard codes to a scope property name

  2. Change the html to <h1 hello name="name"></h1>. This is better but I feel it uses a redundant attribute

  1. 将指令更改为elm.text("hello, " + scope['name']);这不是首选方式,因为它硬编码为范围属性名称

  2. 将 html 更改为<h1 hello name="name"></h1>. 这更好,但我觉得它使用了冗余属性

I would suggest you change the directive to elm.text("hello, " + scope[attrs['hello']]);

我建议您将指令更改为 elm.text("hello, " + scope[attrs['hello']]);

Or even better elm.text("hello, " + scope.$eval(attrs['hello']));

或者更好 elm.text("hello, " + scope.$eval(attrs['hello']));

this way you get the benefit of expressions as well(ex: <h1 hello="name|uppercase"></h1>) demo

这样你得到的表达式的利益以及(例如:<h1 hello="name|uppercase"></h1>演示

This way the html would be <h1 hello="name"></h1>

这样 html 将是 <h1 hello="name"></h1>

Regarding the attrs parameter: it's nothing more than a map of strings taken from the attributes present on the dom element.

关于 attrs 参数:它只不过是从 dom 元素上存在的属性中获取的字符串映射。

回答by vcardillo

You can do something that, as of writing this, appears to be undocumented in Angular (see Mark Rajcok's comment here: http://docs.angularjs.org/api/ng.$rootScope.Scope).

您可以做一些在撰写本文时似乎在 Angular 中没有记录的事情(参见 Mark Rajcok 的评论:http://docs.angularjs.org/api/ng.$ro​​otScope.Scope )。

From within your directive:

从您的指令中:

scope.$parent.name

If you do a console.log(scope)on the directive's scope(from within the directive), you'll see these properties.

如果您console.log(scope)对指令scope(从指令内)执行 a,您将看到这些属性。

All this said, I don't know whether or not this is "proper" Angular convention, due to the fact that this is both undocumented, and I haven't found any other better documentation on how to access the controller that a directive sits within.

所有这一切都说,我不知道这是否是“正确的”Angular 约定,因为这都没有记录,而且我还没有找到任何其他更好的文档来说明如何访问指令所在的控制器在里面。

回答by Mahbub

You can access using scope. Look http://jsfiddle.net/rPUM5/

您可以使用scope. 看http://jsfiddle.net/rPUM5/

directives.directive("hello", function () {
    return function (scope, elm, attrs) {
        elm.text("hello, " + scope.name);
    };
});?

回答by u445908

I found another case:

我发现了另一个案例:

if you are accessing a variable coming from a Ajax request body, then you have to WAIT until the variable is set.

如果您正在访问来自 Ajax 请求正文的变量,那么您必须等待,直到设置了该变量

e.g:

例如:

# in controller
$http.get('/preview').then( (response) ->
  $scope.tabs = response.data.tabs
  $scope.master_switch = '1'
  console.info 'after get response in controller'
)

# in directive
directive('masterSwitch', ->
  (scope, element, attrs) ->
    alert 'in directive!'   # will show before "after get response in controller"
    console.info scope.master_switch  # is undefined
    setTimeout( -> console.info(scope.master_switch), 50) # => 1