如何使用普通JS将对DOM进行的更改传播到其Angular JS绑定上?

时间:2012-12-07 19:07:25

标签: javascript jquery angularjs jquery-ui-sortable

我一直在努力让Angular JS在使用普通JavaScript对其表示的DOM元素进行更改时更新其模型。我不确定我是不是正确编写我的Angular JS代码,或者我是不是正确处理问题。

我有一个带有输入框的可排序列表,其中包含每个项目的排序值。您可以手动输入排序顺序,这将重新排序列表或拖动和放大。删除项目(使用JQuery可排序)。当您使用拖放对项目进行排序时,我会在sortable的更新回调函数中更新输入值,但这似乎不会更新绑定到该输入的Angular JS对象。

我尝试包装我的JS来操作$ scope中的输入值。$ apply但它没有帮助。

这是一个小提琴: http://jsfiddle.net/smelly_fish/d9kt9/1/

这是我的JS:

var sortedShippingMethods = [{
    "id": "UPS 2nd Day Air A.M. ®",
    "name": "UPS 2nd Day Air A.M. ",
    "sort": "0"},
{
    "id": "UPS 3 Day Select ®",
    "name": "UPS 3 Day Select ",
    "sort": "0"},
{
    "id": "UPS Ground",
    "name": "UPS Ground",
    "sort": "2"}];

jQuery(document).ready(function(){

    // Sortable list
    $('#shipping-sort-list').sortable({
        items: 'li',
        axis: 'y',
        containment: 'parent',
        cursor: 'move',
        update: function(event, ui) {
            $scope = angular.element($('#shipping-sort-list')[0]).scope(); 
            $scope.$apply(function(){
                $('#shipping-sort-list input').each(function(i){
                    $(this).attr('value', i+1);
                });
            });
        }
    });
});

function AdminShippingSettingsCtrl($scope) {
    $scope.sortedShippingMethods = sortedShippingMethods;

    $scope.getSortValue = function(sortedShippingMethod) {
        //have to typecast to an int or 3 will show up higher than 23 (string sort ftl)
        var sort = parseInt(sortedShippingMethod.sort, 10);
        return sort;
    }
}​

这是我的标记:

<div id="shipping-sort-list" data-ng-app data-ng-controller="AdminShippingSettingsCtrl">
    <ul>
        <li data-ng-repeat="sortedShippingMethod in sortedShippingMethods | orderBy:[getSortValue, 'name']"><input data-ng-model="sortedShippingMethod.sort" type="text" name="sortOrder[{{sortedShippingMethod.id}}]" value="{{sortedShippingMethod.sort}}" /> {{sortedShippingMethod.name}}</li>
</ul>

<p data-ng-repeat="sortedShippingMethod in sortedShippingMethods">Name: {{sortedShippingMethod.name}} Sort Value: {{sortedShippingMethod.sort}}</p>
</div>
​

1 个答案:

答案 0 :(得分:1)

如果您只是想要答案,请转到:http://jsfiddle.net/d9kt9/4/

阅读说明。您当前迭代的问题是您正在更新元素的值,但实际上您需要更新每个shippingMethod的对象范围。该值只是一个来回传递的值(我知道很奇怪),但是如果你更新一个对象(就像我已经完成的那样)那么它就是通过引用传递的,这可以让你影响主要的sortedShippingMethods。因此,循环使用它们是正确的事情,你可以看到我如何得到每个范围:

$('#shipping-sort-list input').each(function(i){
    var inputScope = angular.element(this).scope();
    inputScope.sortedShippingMethod.sort = i+1;
});

然后在第二个列表的data-ng-repeat上,我添加了与第一个相同的顺序:

<p data-ng-repeat="sortedShippingMethod in sortedShippingMethods | orderBy:[getSortValue, 'name']">