簡體   English   中英

瘋狂使用角度指令和范圍更新

[英]Getting crazy with angular directive and scope update

我正在努力7個小時,以獲取可以工作的東西,目前我正在拔頭發!!!!
難以置信的!

我只想從隔離的指令中更新控制器變量。
瘋狂的是,在視圖中一切正常,但是在控制器中他無法識別變化!

控制器看起來像這樣,因為他是由TypeScript生成的。

/*
ANGULAR CONTROLLER
*/

var CustomerdataTabCtrl = (function () {
    function CustomerdataTabCtrl($scope) {
        $scope.AddressAutocompleteOptions = {};
        $scope.AddressAutocompleteOptions.watchEnter = true;
        $scope.AddressAutocompleteDetails = '';
        $scope.AddressAutocompleteAddress = null;

        $scope.onRoleChange = function () {
            if ($scope.Role == 'Provider') {
                $('#orders-tab-header').css('display', 'none');
            } else {
                $('#orders-tab-header').css('display', 'block');
            }
        };

        $scope.onAddressAutocompleteChange = function () {
            alert('asd');
        };

        $scope.$watch('Role', function () {
            return $scope.onRoleChange();
        }, true);
        $scope.$watch('AddressAutocompleteAddress', function () {
            return $scope.onAddressAutocompleteChange();
        }, true);
    }
    return CustomerdataTabCtrl;
})();

/*
ANGULAR DIRECTIVE
*/
angular.module("ngAutocomplete", [])
    .directive('ngAutocomplete', function () {
        return {
            require: 'ngModel',
            scope: {
                ngModel: '=',
                options: '=',
                details: '=',
                address: '='
            },

            link: function (scope, element, attrs, controller) {

                //options for autocomplete
                var opts;
                var watchEnter = false;
                //convert options provided to opts
                var initOpts = function () {

                    opts = {};
                    if (scope.options) {

                        if (scope.options.watchEnter !== true) {
                            watchEnter = false
                        } else {
                            watchEnter = true
                        }

                        if (scope.options.types) {
                            opts.types = [];
                            opts.types.push(scope.options.types);
                            scope.gPlace.setTypes(opts.types)
                        } else {
                            scope.gPlace.setTypes([])
                        }

                        if (scope.options.bounds) {
                            opts.bounds = scope.options.bounds;
                            scope.gPlace.setBounds(opts.bounds)
                        } else {
                            scope.gPlace.setBounds(null)
                        }

                        if (scope.options.country) {
                            opts.componentRestrictions = {
                                country: scope.options.country
                            };
                            scope.gPlace.setComponentRestrictions(opts.componentRestrictions);
                        } else {
                            scope.gPlace.setComponentRestrictions(null);
                        }
                    }
                };

                if (scope.gPlace == undefined) {
                    scope.gPlace = new google.maps.places.Autocomplete(element[0], {});
                }

                google.maps.event.addListener(scope.gPlace, 'place_changed', function () {
                    var result = scope.gPlace.getPlace();
                    if (result !== undefined) {
                        if (result.address_components !== undefined) {
                            scope.$apply(function () {
                                scope.address = parseGoogleResponse(result.address_components);
                                scope.details = result;
                                controller.$setViewValue(element.val());
                            });
                        }
                        else {
                            if (watchEnter) {
                                getPlace(result)
                            }
                        }
                    }
                });

                //function to get retrieve the autocompletes first result using the AutocompleteService
                var getPlace = function (result) {
                    ...                    
                };


                var parseGoogleResponse = function(components) {
                    var result = {};

                    for (var i = 0; i < components.length; i++) {
                        var addressType = components[i].types[0];
                        result[addressType] = components[i]['long_name'];
                    }

                    return result;
                };


                controller.$render = function () {
                    var location = controller.$viewValue;
                    element.val(location);
                };

                //watch options provided to directive
                scope.watchOptions = function () {
                    return scope.options
                };
                scope.$watch(scope.watchOptions, function () {
                    initOpts()
                }, true);
            }
        };
    });

HTML

<div ng-controller="CustomerdataTabCtrl">
<input type="text" id="customerdata_quick_auto_address" name="customerdata_quick_auto_address" class="form-control input-sm" ng-autocomplete ng-model="AddressAutocomplete" options="AddressAutocompleteOptions" details="AddressAutocompleteDetails" address="AddressAutocompleteAddress" />
{{AddressAutocompleteAddress.route}}
</div>

就像我說的那樣,視圖輸出正確的結果,但是控制器監視僅在init上觸發一次,但不會再觸發,但這是相同的fu ....變量。 視圖{{AddressAutocompleteAddress.route}}使用控制器作用域變量,我真的很瘋狂!

親切的問候

就像我在評論中提到的那樣,這是變量范圍的問題。 該指令的隔離范圍使其成為AddressAutocompleteAddress變量的自己的實例,因為它是“原始”變量。 解決此問題的方法是使用“。” (點)表示法。

我可能會對您的代碼執行的操作是創建一個名為AddressAutocomplete的對象,然后將其他變量添加到該對象。

function CustomerdataTabCtrl($scope) {
    $scope.AddressAutocomplete = {};
    $scope.AddressAutocomplete.Text = '';
    $scope.AddressAutocomplete.Options = {};
    $scope.AddressAutocomplete.Options.watchEnter = true;
    $scope.AddressAutocomplete.Details = '';
    $scope.AddressAutocomplete.Address = null;
    ...
}

並在您的html中:

<div ng-controller="CustomerdataTabCtrl">
    <input type="text" id="customerdata_quick_auto_address" 
       name="customerdata_quick_auto_address"
       class="form-control input-sm" ng-model="AddressAutocomplete.Text" 
       ng-autocomplete options="AddressAutocomplete.Options"
       details="AddressAutocomplete.Details" address="AddressAutocomplete.Address" />
    {{AddressAutocomplete.Address.route}}
</div>

只要記住要更新在控制器中使用變量的方式即可。 另外,我也看不到您在指令中使用ng-model變量的位置,因此我不確定為什么要在其中使用它。

還有一點,您真的不應該在指令中使用ng-前綴,這是AngularJs庫中指令的保留前綴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM