停止对angular指令的双向数据绑定

时间:2016-09-01 18:49:38

标签: javascript angularjs

我想将信息传递给这样的指令:

<ui-message data="{{app}}"></ui-message>

我的控制器中有以下内容:

app.controller("testCtrl", function($scope) {
  $scope.app = "Hello World!"
})

我的指示:

app.directive("uiMessage", function() {
  return {
    template: "<h1>{{message}}</h1>",
    scope: {
      message: "@data"
    }
  }
})

这样可行,但如果app绑定到模型,它将更新指令内的内容:

<input ng-model="app"> //typing here changes the content inside ui-message
<ui-message data="{{app}}"></ui-message>

如何防止这种情况发生?

2 个答案:

答案 0 :(得分:2)

单向绑定&#34; @&#34;与您正在思考的方向相反 - 它可以防止指令中的更改被复制回父作用域,而不会阻止父作用域中的更改影响指令。您可能想要做的是使用angular.copy复制数据,然后将该副本传递给您的指令。

app.controller("testCtrl", function($scope) {
  $scope.app = "Hello World!"
  $scope.appCopy = angular.copy($scope.app);
})

此时,您的模板中不需要单向数据绑定:

<ui-message data="appCopy"></ui-message>

或你的指示

app.directive("uiMessage", function() {
  return {
    template: "<h1>{{message}}</h1>",
    scope: {
      message: "=data"
    }
  }
})

答案 1 :(得分:2)

您可以将one time binding expression::

一起使用

function uiMessage() {
  return {
    template: "<h1>{{::msg}}</h1>",
    scope: {
      msg: "="
    }
  }
}
function myController($scope) {
  $scope.message = "one way";
}
angular.module('myApp', []);
angular
    .module('myApp')
    .controller('myController', myController)
    .directive('uiMessage', uiMessage);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="myController">
    <input type="text" ng-model="message" />
    <ui-message msg="message"></ui-message>
  </div>
</div>

如果您真的只是一次性的事情而且您不需要变量,那么您可以使用ng-transclude而不是创建范围:

function uiMessage() {
  return {
    transclude: true,
    template: "<h1 ng-transclude></h1>"
  }
}
function myController($scope) {
  $scope.message = "one way";
}
angular.module('myApp', []);
angular
    .module('myApp')
    .controller('myController', myController)
    .directive('uiMessage', uiMessage);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="myController">
    <input type="text" ng-model="message" />
    <ui-message>{{::message}}</ui-message>
  </div>
</div>