【问题标题】:Scope of Controller in Directive using Typescript on AngularJS在 AngularJS 上使用 Typescript 的指令中控制器的范围
【发布时间】:2015-08-27 16:47:00
【问题描述】:

我正在继续学习 Typescript 和 AngularJS,并且对范围有疑问。我正在做一个项目,项目中的每个人都负责一个指令。但是,我最近在我的理解中遇到了障碍。

目前我有一个 html 页面,其中包含以下内容

<html ng-app ="helloworld">
    <head>
        <!--insert scripts here-->
    </head>
    <body>
       <direct-a></direct-a>
       <hello-world></hello-world>
    </body>
</html>

我们已将指令设置为类似于以下内容:

/// <reference path="../../../typings/tsd.d.ts" />
module helloWorld{

var app :angular.IModule = angular.module('helloWorld');

app.directive('helloWorld', HelloWorldDirective);

    function HelloWorldDirective() :ng.IDirective{

        return <ng.IDirective>{
            controller: 'HelloWorldController',
            controllerAs : 'vm',
            templateUrl: './app/HelloWorld/HelloWorld.html'          

        };

};

}

我在&lt;direct-a&gt; 指令上有与此类似的代码,但使用该代码,我无法看到&lt;hello-world&gt; 标记中的任何内容,直到我们将controllerAs 更改为“vm”以外的其他内容。这让我想知道我们是否需要为自定义指令设计命名约定,而不是为controllerAs 使用“vm”短语?还是我在这里缺少一个技巧?

【问题讨论】:

    标签: javascript angularjs angularjs-scope typescript


    【解决方案1】:

    我创建了两个示例:

    坏了

    这就是我创建&lt;hello-world&gt;指令的方式(与此How can I define my controller using TypeScript?相关)

    module HelloWorld
    {
        var app = angular.module('TheApp');
        
        export class HelloWorldDirective implements ng.IDirective
        {
            public restrict: string = "E";
            public replace: boolean = true;
            public template: string = "<div>" +
                "<input ng-model=\"vm.MyValue\" />" +
                "<button ng-click=\"vm.Show()\" >Show my value</button>" +
                "<p> my value <b>{{vm.MyValue}}</b></p>" +
                "</div>";
            public controller: string = 'HelloWorldCtrl';
            public controllerAs: string = 'vm';
            //public scope = {};
        }    
        app.directive("helloWorld", [() => new HelloWorld.HelloWorldDirective()]);
    
        export interface IHelloWorldScope  extends ng.IScope
        {
            // properties for isolated scope
        }
        export class HelloWorldCtrl
        {
            static $inject = ["$scope"];
            constructor(protected $scope: HelloWorld.IHelloWorldScope){ }
            public MyValue: string = "InitValue";
            public Show(): void
            {
                alert(this.MyValue)
            }
        }
        app.controller('HelloWorldCtrl',  HelloWorld.HelloWorldCtrl);
    }
    

    这是 &lt;other-directive&gt; TypeScript 代码:

    module OtherDirective
    {
        var app = angular.module('TheApp');
        
        export class OtherDirectiveDirective implements ng.IDirective
        {
            public restrict: string = "E";
            public replace: boolean = true;
            public template: string = "<h4>" +
                "OtherValue: {{vm.OtherValue}}" +
                "</h4>";
            public controller: string = 'OtherDirectiveCtrl';
            public controllerAs: string = 'vm';
            //public scope = {};
        }
    
        app.directive("otherDirective", [() => new OtherDirective.OtherDirectiveDirective()]);
    
        export interface IOtherDirectiveScope  extends ng.IScope
        {
          // properties for isolated scope
        }
        export class OtherDirectiveCtrl
        {
            static $inject = ["$scope"];
            constructor(protected $scope: OtherDirective.IOtherDirectiveScope) {}
            public OtherValue: string = "This is other Value";
        }
        app.controller('OtherDirectiveCtrl',  OtherDirective.OtherDirectiveCtrl);
    }
    

    所以,如果我们将这两个并排放置:

    <div>
        <hello-world></hello-world>
        <other-directive></other-directive>
    </div>
    

    &lt;hello-world&gt; 不起作用。它会被打破。原因是“共享”不是独立作用域,两个指令都可以访问。

    让它工作

    要修复它,我们必须同时更改(在这个简单的示例中至少要更改一个)或者为controllerAs使用不同的名字

    查看文档 (Angular Directive Guide)

    隔离指令的范围

    我们上面的 myCustomer 指令很棒,但它有一个致命的缺陷。我们只能在给定范围内使用一次。
    ...
    我们希望能够做的是将指令内部的作用域与外部作用域分开,然后将外部作用域映射到指令的内部作用域。我们可以通过创建我们所说的隔离作用域来做到这一点。为此,我们可以使用指令的范围选项:

    这里我们将要求隔离范围

    export class HelloWorldDirective implements ng.IDirective
    {
        public restrict: string = "E";
        public replace: boolean = true;
        public template: string = "<div>" +
            "<input ng-model=\"vm.MyValue\" />" +
            "<button ng-click=\"vm.Show()\" >Show my value</button>" +
            "<p> my value <b>{{vm.MyValue}}</b></p>" +
            "</div>";
        public controller: string = 'HelloWorldCtrl';
        public controllerAs: string = 'vm';
        // isolated scope requested
        public scope = {};
    }
    
    export class OtherDirectiveDirective implements ng.IDirective
    {
        public restrict: string = "E";
        public replace: boolean = true;
        public template: string = "<h4>" +
            "OtherValue: {{vm.OtherValue}}" +
            "</h4>";
        public controller: string = 'OtherDirectiveCtrl';
        public controllerAs: string = 'vm';
        // isolated scope requested as well
        public scope = {};
    }
    

    在行动中检查它here 有关此方法的更多信息:

    【讨论】:

    • 如果有帮助就太好了;)
    • 帮助很大:)
    猜你喜欢
    • 2015-01-11
    • 2016-05-25
    • 2014-07-13
    • 2013-05-28
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    相关资源
    最近更新 更多