当我更改模型时为什么输入不会更新?

时间:2013-07-12 18:46:56

标签: javascript angularjs

http://jsfiddle.net/waGEU/1/

尝试在单击列表时添加或删除列表中的元素,但似乎没有删除正确的元素,尽管最初添加它们似乎有效。

javascript

angular.module('app', [])
    .controller('MainCtrl', function($scope) {
        $scope.tags = ['a', 'b', 'c']
        $scope.book = {tags: []}
        $scope.toggle_tag = function(tag) {
            index = $scope.book.tags.indexOf(tag)
            if (index == -1)
                $scope.book.tags.push(tag)
            else
                $scope.book.tags.splice(tag, 1)
        }
    });

HTML

<div ng-app="app" ng-controller="MainCtrl">
    <input type="text" ng-model="book.tags" ng-list="/ /" />
    <p>{{book.tags}}</p>
    <span class="tag" ng-repeat="tag in tags" ng-click="toggle_tag(tag)">{{tag}}</span>
</div>

可以单击标签来添加或删除标签。我将ng-model添加到输入中。但是当我点击它时,输入将不会更新。我怎样才能让它更新。

3 个答案:

答案 0 :(得分:3)

未更新输入,因为您未设置/绑定其value属性。

更改此行

<input type="text" ng-model="book.tags" ng-list="/ /" />

这样的事情

<input type="text" value="{{book.tags.join(',')}}" />

还要检查shaunhusain的答案,以修复你所遇到的拼接错误。

更新了两个修补程序:http://jsfiddle.net/waGEU/6/

答案 1 :(得分:2)

Splice希望索引不是要移除的元素

http://jsfiddle.net/waGEU/2/

JS

angular.module('app', [])
    .controller('MainCtrl', function($scope) {
        $scope.tags = ['a', 'b', 'c']
        $scope.book = {tags: []}
        $scope.toggle_tag = function(tag) {
            index = $scope.book.tags.indexOf(tag)
            if (index == -1)
                $scope.book.tags.push(tag)
            else
                $scope.book.tags.splice(index, 1)
        }
    });

改变

                $scope.book.tags.splice(tag, 1)

                $scope.book.tags.splice(index, 1)

关于绑定的另一个问题是不更新输入:

http://jsfiddle.net/waGEU/5/

angular.module('app', [])
    .controller('MainCtrl', function($scope) {
        $scope.tags = ['a', 'b', 'c'];
        $scope.book = {tags: [], displayTag:""};
        $scope.toggle_tag = function(tag) {
            index = $scope.book.tags.indexOf(tag)
            if (index == -1)
                $scope.book.tags.push(tag)
            else
                $scope.book.tags.splice(tag, 1)
            $scope.book.displayTag = $scope.book.tags.slice(0);
        }
    });

然后将输入绑定到books.displayTag

我认为这里的问题可能类似于AS3 Bindings遇到的问题,当更改数组中的底层元素时,它不会被视为对数组本身的更改。也许这是不同的,如果是这样我也想进一步澄清。

我上面的代码“有效”,但绝对没有效率,因为我基本上每次克隆数组,请参阅使用的答案:

<input type="text" value="{{book.tags.join(',')}}" />

改为进行绑定更新。

答案 2 :(得分:0)

对于双向绑定解决方案,您可以引入额外的变量

<input type="text" ng-model="book.tagInputValue" />

并使用book.tags

$scope.$watch数组保持同步
$scope.$watch('book.tags',
    function(newValue, oldValue, scope) {
        scope.book.tagInputValue = newValue.join(' ');
    },
    true
);

$scope.$watch('book.tagInputValue',
    function(newValue, oldValue, scope) {
        scope.book.tags = (newValue && newValue.length > 0) ?
            newValue.split(/\s+/) : [];
    }
);

以下是更新的jsFiddle:http://jsfiddle.net/waGEU/9/

你可以把所有这些放在你自己的指令中,特别是如果你打算有一个书籍列表,这些书籍将全部使用这样的输入。 请参阅:http://docs.angularjs.org/guide/directive#writingdirectivesshortversion

但是,更新这样的输入字段值有时会导致carret位置切换到末尾(例如删除标记时)。