AngularJS ng-model没有做双向数据绑定

时间:2017-02-11 17:25:02

标签: angularjs data-binding angularjs-scope

我有一个带有输入框的标签,如下所示:

  <label class="item item-input">
    <input type="text" data-ng-model="description" placeholder="Add a Description!">
  </label>

如您所见,此输入框绑定到范围“description”

在我的控制器中,我有类似的内容:

$scope.description = "";
$scope.submit = function() {
    console.log($scope.description);
};

在我的HTML中,我也有这一行:

  <div ng-show="description.length <= maxChars">{{description}}</div>

当用户在输入框内输入后点击提交按钮时,将调用submit函数。说明正确显示。当用户键入输入框时,描述会在HTML中更新,但不会在控制器中更新。

我觉得它与将描述设置为空字符串有关,但就HTML而言,它显然已经更新了。但无论如何,它都会保留console.logging和空字符串。

为了使其工作,我必须直接将描述传递给提交函数(并相应地更新函数):

<button class="button button-positive" data-ng-click="submit(description)">Submit</button>

这是完全没必要的,因为Angular应该自动进行双向数据绑定,但事实并非如此。

有人有什么想法吗?

任何帮助都将不胜感激。

编辑:

由于受欢迎的需求,这是完整的HTML。

<ion-view title="Moments" id="page2">
<ion-content padding="true" class="has-header">
<img src="{{picture}}" height="300px" width="100%"> </img>
<div class="row">
  <div ng-show="description.length > maxChars" style= "color: red">{{description}}</div>
  <div ng-show="description.length <= maxChars">{{description}}</div>
</div>
<div class="row" ng-if="description">
  <div ng-show="description.length > maxChars" style= "color: red">{{description.length}} / {{maxChars}}</div>
  <div ng-show="description.length <= maxChars" style= "color: green">{{description.length}} / {{maxChars}}</div>
</div>
<div class="row">
    <div class="col">
      <label class="item item-input">
        <input type="text" data-ng-model="description" placeholder="Add a Description!">
      </label>
    </div>
    <button style="margin-right: 5px" class="col col-10 button button-positive" data-ng-click="checkDescription(description)">OK</button>
</div>
<div class="row">
  <div class="col"><ion-checkbox data-ng-change="changeLocation()" data-ng-model="location">Show Location</ion-checkbox></div>
</div>
<div class="row">
  <div class="button-bar">
    <button class="button button-assertive" data-ng-click="cancel()">Cancel</button>
    <button class="button button-positive" data-ng-click="submit(description)">Submit</button>
  </div>
</div>
</ion-content>
</ion-view>

我也知道在这个问题中,submit函数不带参数。这就是我希望的样子。目前我的提交按钮有一个参数(描述)。这不应该是必要的。我也遇到了与'checkDescription'功能相同的问题。该函数也应该没有参数但是我又被迫将描述直接传递给函数。我不想做的事情。

2 个答案:

答案 0 :(得分:2)

  

执行摘要:

     

在AngularJS中,子范围通常原型继承自其父范围。此规则的一个例外是使用scope: { ... }的指令 - 这会创建一个&#34; isolate&#34;没有原型继承的范围。(和带有翻译的指令)这个结构通常用于创建一个&#34;可重用的组件&#34;指示。在指令中,默认情况下直接使用父作用域,这意味着您在指令中更改的来自父作用域的任何内容也将在父作用域中更改。如果设置scope:true(而不是范围:{ ... }),那么原型继承将用于该指令。

     

范围继承通常很简单,你甚至不需要知道它正在发生......直到你尝试双向数据绑定(即表格元素,ng- model)到原始(例如,数字,字符串,布尔值)在子范围内从父范围定义。它没有像大多数人期望的那样工作。会发生什么是子范围获取其自己的属性,该属性隐藏/隐藏同名的父属性。这不是AngularJS正在做的事情 - 这就是JavaScript原型继承的工作原理。新的AngularJS开发人员通常不会意识到ng-repeatng-switchng-viewng-includeng-if都会创建新的子范围,因此问题经常出现在涉及这些指令。 (有关问题的快速说明,请参阅this example。)

     

通过遵循&#34;最佳实践&#34;可以很容易地避免使用原语这个问题。 always have a dot '.' in your ng-models - 观看3分钟。 Misko用ng-switch演示了原始绑定问题。

     

--AngularJS Wiki -- The Nuances of Scope Prototypal Inheritance

  

我试图做&#39;。&#39;我的范围中的符号,但每当我尝试像这样引用它时:

$scope.moment.description = ""; 
     

它说&#34;无法阅读财产&#39;描述&#39; undefined

代码需要在为属性赋值之前创建对象:

$scope.moment = {};
$scope.moment.description = "";

//OR

$scope.moment = { description: "" };    

答案 1 :(得分:0)

为了跟踪价值更新,您可以使用$ watch,

scope.$watch('description', function(newValue, oldValue) {
    console.log(newValue);
 });