如何在angular指令中访问孤立的'this'范围?

时间:2015-09-29 16:40:39

标签: angularjs angularjs-directive

如果我使用$ scope,这个指令可以完美地运行:

function alertBox(){
  return {
    template: 
      '<div ng-show="alert" class="alert alert-{{alert.type}}" style="text-align: center;">\
         <a href="#" class="close" data-dismiss="alert" aria-label="close" title="close">x</a>\
         <span ng-bind-html="alert.message | safe_html"></span>\
       </div>'
  }
}

警报在我的控制器中定义为:

$scope.alert = {message: 'test!', type: 'danger'};

我的简单观点:

<div alert-box></div>

但是,我不使用$ scope,而是使用'this'定义警报:

this.alert = {message: 'test!', type: 'danger'};

但无论我尝试什么,我都无法弄清楚如何将'this'的值注入指令。

理想情况下,我可以引用'self.alert'或其他东西,这样我就不必将范围上下文定义为属性,但假设我这样做,我尝试过这种变化无济于事:

function alertBox(){
    return {
        scope: {
            scope: '=scope'
        },
        template: '<div ng-show="' + scope + '.alert" class="alert alert-' + scope + '.type" style="text-align: center;"><a href="#" class="close" data-dismiss="alert" aria-label="close" title="close">x</a>        <span ng-bind-html="' + scope + '.message | safe_html"></span></div>'
    }
}

我的HTML:

<div alert-box scope="welcome"></div>

在那个例子中,我已经定义了'WelcomeController as welcome'

感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

这里有几个误解的问题。

首先,具有自己模板的指令通常使用隔离范围,这样模板操作的范围与指令操作的范围不同。这就是使指令可重复使用的原因。

在您的原始示例中,该指令使用父作用域(带有隐式scope: false)而不是隔离作用域(scope: {})。

第二次,您尝试将&#34;控制器用作&#34;接近并将alert对象定义为控制器实例的属性。然后,控制器实例(您称之为this)将在示例中的控制器别名 - welcome下的范围内发布。因此,您需要{{alert.message}}而不是{{welcome.alert.message}}。这就是&#34;控制器作为&#34;确实 - 把这个&#34;这个&#34; (即控制器实例对象)为$scope.<alias>

所以(并且仍然),适用范围的原则,如我的第一点所述,适用。

===

为了使您的示例有效,请使用isolate scope创建一个指令,并通过属性绑定绑定对象alert

以下是规范(虽然浪费,见下文)这样做的方式:

.directive("alertBox", function(){
  return {  
    scope: {
      alert: "="
    },
    template: '<div ng-show="alert" class="alert-{{alert.type}}">{{alert.message}}</div>'
  };
})

用法:

<div ng-controller="WelcomeController as welcome">
  <div alert-box alert="welcome.alert"></div>
</div>
// in WelcomeController
this.alert = {message: 'test!', type: 'danger'};

指令的模板不受在作用域上设置传入的alert对象的影响。

红利部分

那么,为何浪费?

"="范围绑定会创建双向绑定,这在此处可能是不必要的,因为预期指令alertBox不会修改父级的alert对象。双向绑定设置2个观察者,其中一个未使用,因此浪费。

相反,您可以使用"&"单向绑定到表达式。 "&"提供了一个函数,需要调用它来获取绑定表达式返回的对象(而不是直接与"="一样的对象),因此指令的模板稍微改变为: / p>

scope: {
  alert: "&",
},
template: '<div ng-show="alert()" class="alert-{{alert().type}}">{{alert().message}}</div>'

答案 1 :(得分:-1)

bindToController:您可以使用bindToController属性,当在范围隔离的指令中设置为true时,组件属性绑定到controller而不是scope,这使得它可以在this上找到。

通常,在使用controller as语法时,您会执行类似的操作。

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

myapp.controller('MainCtrl', function () {
    this.name = "Vinoth Babu";
});

myapp.directive('alertBox', function(){    
    return {
        controller: 'MainCtrl',
        controllerAs: 'ctrl',
        bindToController: true,
        template: '<div>{{ctrl.name}}</div>'
    };    
});

HTML代码段

<div ng-app="myapp">
    <div ng-controller="MainCtrl as ctrl">
        <div alert-box></div>
    </div>
</div>

工作小提琴:http://jsfiddle.net/SNF9x/136/

如果你有别的想法,请告诉我。