AngularJS:$ watch没有被指令触发

时间:2014-08-11 16:19:41

标签: angularjs directive watch

这是我的指示:

    directive('chosen', function ($timeout, $rootScope) {
        var linker = function (scope, element, attrs) {

            scope.$watch('chosenModelList', function () {
                element.trigger('chosen:updated');
                console.log('chosen:updated');
                $timeout(function() {
                    element.trigger('chosen:updated');
                }, 100);

                if (!$rootScope.$$phase)
                    $rootScope.$apply();
            }, true);

            scope.$watch('chosenModel', function () {
                element.trigger('chosen:updated');
                $timeout(function () {
                    element.trigger('chosen:updated');
                }, 100);

                if (!$rootScope.$$phase)
                    $rootScope.$apply();
            }, true);

            element.chosen({
                display_selected_options: false,
                max_selected_options: "3",
                disable_search_threshold: 1000
            });
        };

        return {
            restrict: 'A',
            scope: {
                'chosenModelList': '=',
                'chosenModel': '='
            },
            link: linker
        };
    })

这是我在HTML中使用它的方式:

                <select class="form-control" id="BusinessLocations" name="businessLocations" **chosen chosen-model-list="businessLocations"** multiple="" data-placeholder="Select one or more location"
                        data-ng-model="listing.locations"
                        required ng-focus
                        data-ng-options="businessLocation.id as businessLocation.address for businessLocation in businessLocations"></select>

模型在控制器中以这种方式更新:

                $scope.listing.businessOwner = $scope.$parent.businessId;
                if (!modifying) {
                    $scope.getLocations($scope.listing.businessOwner).then(function (locations) {
                        **$scope.businessLocations = locations;**
                        console.log('businesLocations');
                        if (locations.length === 1) {
                            $scope.listing.locations = [$scope.businessLocations[0].id];
                        }
                    });
                    mixpanelService.track('Listing Create Form');
                } else {
                    listingService.getListings({ 'id': $location.search().id, 'includeLocations': true, 'includeBusiness': true }).then(function (listings) {
                        $scope.getLocations(listings[0].businessOwnerId).then(function (locations) {
                            **$scope.businessLocations = locations;**
                            console.log('businesLocations');
                            $scope.listing = listings[0];
                            $scope.listing.businessOwner = $scope.listing.businessOwnerId;
                            var locationIds = [];
                            for (var i = 0; i < $scope.listing.locations.length; i++) {
                                locationIds.push($scope.listing.locations[i].id);
                            }
                            $scope.listing.locations = locationIds;
                        });
                    });
                    mixpanelService.track('Listing Edit Form');
                }
随着businessLocations模型的更新,手表不会被触发。 相同的指令在代码的其他部分工作,我以相同的方式使用它。

虽然不需要传递true作为$ watch的第三个参数,但我只是尝试过,如果这样可行,但没有成功。 $ rootScope。$ apply()也是出于同样的原因。

2 个答案:

答案 0 :(得分:0)

尝试以下方法:

  1. 使用$ observe代替$ watch。按照 this link 了解原因。
  2. 使用以下html:
  3. <select class="form-control" id="BusinessLocations" name="businessLocations" chosen chosen-model-list="{{businessLocations}}" multiple="" data-placeholder="Select one or more location" data-ng-model="listing.locations" required ng-focus data-ng-options="businessLocation.id as businessLocation.address for businessLocation in businessLocations"></select>

答案 1 :(得分:0)

这对我有用。

指令:

directive('chosen', function ($timeout) {
    var linker = function (scope, element, attrs) {

        scope.$watch('chosenModelList', function (value) {
            element.trigger('chosen:updated');
        });

        scope.$watch('chosenModel', function (value) {
            element.trigger('chosen:updated');
        });

        element.chosen({
            display_selected_options: false,
            max_selected_options: scope.maxSelectedOptions || 3,
            disable_search_threshold: 1000
        });
    };

    return {
        restrict: 'A',
        scope: {
            'chosenModelList': '=',
            'chosenModel': '=',
            'maxSelectedOptions': '='
        },
        link: linker
    };
})

HTML:

<select class="form-control" id="BusinessLocations" name="businessLocations" data-placeholder="Select one or more location"
    chosen
    chosen-model-list="businessLocations"
    chosen-model="listing.locations"
    max-selected-options="1000"
    multiple=""
    data-ng-model="listing.locations"
    required ng-focus
    data-ng-options="businessLocation.id as businessLocation.address for businessLocation in businessLocations"></select>