如何使我的ng-include模板具有双向绑定?

时间:2017-01-10 10:45:13

标签: angularjs

我有一个tab-content组件,它从控制器获取动态URL

<tab-content url="{{tabContentUrl}}"></tab-content>

组件的指令:

myApp.directive("tabContent", () => {
    return {
        restrict: "E",
        scope: true,
        link: (scope, element, attrs) => {
            scope.getContentUrl = () => {
                return attrs.url || "views/new-week-stats.html";
            }
        },
        template: "<div ng-include='getContentUrl()'></div>"
    }
});

此时,它只能在控制器中注入$ scope的初始值。当在范围中更改某些内容时,它不会在DOM中刷新。如何在指令中启用双向绑定?

4 个答案:

答案 0 :(得分:1)

ngInclude指令已经为你做了你想要的,只需使用指令范围2路绑定。

myApp.directive("tabContent", () => {
    return {
        restrict: "E",
        scope: {
            url: '='
        },
        template: '<div ng-include="url || 'views/new-week-stats.html'"></div>'
    }
});

这样,url元素tabContent上的任何更改都会触发ngInclude的更改。

答案 1 :(得分:1)

快速回答

您有两种选择。

  
      
  1. 与具有双向绑定(scope:false)的父级相同的范围:
  2.   

HTML:

<tab-content ng-model="tabContentUrl"></tab-content>

JS:

myApp.controller("MainCtrl", function($scope){
    $scope.default = "views/new-week-stats.html";
    $scope.tabContentUrl = "views/example.html";
});

myApp.directive("tabContent", () => {
    return {
        restrict: "E",
        scope: false,
        template: "<div ng-include='tabContentUrl || default'></div>"
    }
});
  
      
  1. 具有双向绑定的隔离范围(scope:{url: '='}):
  2.   

HTML:

<div ng-controller="MainCtrl">
    <tab-content url="tabContentUrl" default="views/new-week-stats.html">
    </tab-content>
</div>

JS:

myApp.controller("MainCtrl", function($scope){
    $scope.tabContentUrl = "views/example.html"
});

myApp.directive("tabContent", () => {
    return {
        restrict: "E",
        scope: {
            url: '=',
            default: '@'
        },
        template: "<div ng-include='url || default'></div>"
    }
});

<小时/>

说明:

所有指令都有与之关联的范围。他们使用此范围来访问模板和链接功能中的数据/方法。默认情况下,除非明确设置,否则指令不会创建自己的范围。因此,指令使用它们的父作用域(通常是控制器)作为它们自己的作用。

在第4行的代码中,您指定了scope: true,

当指令范围设置为“true”时,AngularJS将创建一个新的范围对象并分配给该指令。这个新创建的范围对象是从其父范围(使用它的控制器范围)原型继承的。

总共有三种选择:

  

与具有双向绑定的父级相同的范围。

scope: false,
  

隔离范围但单向绑定。

scope: true,
  

带选项的隔离范围。

scope: {
    "@"   // Creates a copy as text
    "="   // Direct model with two-way binding
    "&"   // For passing functions
}

答案 2 :(得分:0)

在你的指令中添加一个观察者:

HTML

<tab-content url="tabContentUrl"></tab-content>

JS

myApp.directive( "tabContent", () => {
    return {
        restrict: "E",
        scope   : true,
        link    : ( scope, element, attrs ) => {
            scope.$watch( () => scope.$eval( attrs.url ), newValue => {
                scope.url = newValue;
            } );

        },
        template: "<div ng-include='url'></div>"
    };
} );

你也可以使用$ parse而不是$ eval,但是你没有一个孤立的范围,所以它应该没问题,只要你不覆盖指令中的参数

答案 3 :(得分:0)

您可以使用观察者动态更改指令中的范围值。

link: function(scope, element, attrs){
      attrs.$observe('tabContentUrl', function(val) {
        scope.tabContentUrl = val;
      })
}