Javascript 角度指令和范围更新让人抓狂

Javascript 角度指令和范围更新让人抓狂,javascript,angularjs,typescript,Javascript,Angularjs,Typescript,我现在花了7个小时来做一些工作,现在我正在努力工作 难以置信 我只想从独立指令更新控制器变量。 疯狂的是,在视图中,一切工作都很完美,但在控制器中,他不认识到变化 控制器看起来像这样,因为它是由TypeScript生成的 /* ANGULAR CONTROLLER */ var CustomerdataTabCtrl = (function () { function CustomerdataTabCtrl($scope) { $scope.AddressAutocom

我现在花了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);
            }
        };
    });
/*
角度控制器
*/
var CustomerdataTabCtrl=(函数(){
函数CustomerdataTabCtrl($scope){
$scope.AddressAutocompleteOptions={};
$scope.AddressAutocompleteOptions.watchEnter=true;
$scope.AddressAutoCompletedDetails='';
$scope.AddressAutocompleteAddress=null;
$scope.onRoleChange=函数(){
如果($scope.Role=='Provider'){
$(“#订单选项卡标题”).css('display','none');
}否则{
$(“#订单选项卡标题”).css('display','block');
}
};
$scope.onAddressAutocompleteChange=函数(){
警报(“asd”);
};
$scope.$watch('Role',function(){
返回$scope.onRoleChange();
},对);
$scope.$watch('AddressAutocompleteAddress',函数(){
返回$scope.onAddressAutocompleteChange();
},对);
}
返回CustomerdataTabCtrl;
})();
/*
角度指令
*/
角度模块(“自动完成”,[])
.指令('ngAutocomplete',函数(){
返回{
要求:'ngModel',
范围:{
ngModel:“=”,
选项:“=”,
详情:“=”,
地址:'='
},
链接:功能(范围、元素、属性、控制器){
//自动完成选项
var选择;
var-watchEnter=false;
//将提供的选项转换为选项
var initOpts=函数(){
opts={};
if(范围选项){
if(scope.options.watchEnter!==true){
watchEnter=false
}否则{
watchEnter=true
}
if(scope.options.types){
opts.types=[];
opts.types.push(scope.options.types);
scope.gPlace.setTypes(opts.types)
}否则{
scope.gPlace.setTypes([])
}
if(scope.options.bounds){
opts.bounds=scope.options.bounds;
scope.gPlace.setBounds(opts.bounds)
}否则{
scope.gPlace.setBounds(null)
}
if(范围、选项、国家){
opts.componentRestrictions={
国家:scope.options.country
};
scope.gPlace.setComponentRestrictions(opts.componentRestrictions);
}否则{
scope.gPlace.setComponentRestrictions(null);
}
}
};
if(scope.gPlace==未定义){
scope.gPlace=new google.maps.places.Autocomplete(元素[0],{});
}
google.maps.event.addListener(scope.gPlace,'place\u changed',函数(){
var result=scope.gPlace.getPlace();
如果(结果!==未定义){
if(result.address_components!==未定义){
作用域:$apply(函数(){
scope.address=parseGoogleResponse(result.address\u组件);
scope.details=结果;
控制器.$setViewValue(element.val());
});
}
否则{
如果(监视输入){
getPlace(结果)
}
}
}
});
//函数获取并使用AutocompleteService检索自动完成的第一个结果
var getPlace=函数(结果){
...                    
};
var parseGoogleResponse=函数(组件){
var result={};
对于(var i=0;i
HTML


{{AddressAutocompleteAddress.route}
就像我说的,视图输出正确的结果,但是控制器手表只在init上触发一次,但再也不会触发,但它是相同的fu。。。。变量视图{{AddressAutocompleteAddress.route}}使用了控制器范围变量,我快疯了


正如我在评论中提到的,这是变量范围的问题。该指令的隔离范围正在生成它自己的
<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>
function CustomerdataTabCtrl($scope) {
    $scope.AddressAutocomplete = {};
    $scope.AddressAutocomplete.Text = '';
    $scope.AddressAutocomplete.Options = {};
    $scope.AddressAutocomplete.Options.watchEnter = true;
    $scope.AddressAutocomplete.Details = '';
    $scope.AddressAutocomplete.Address = null;
    ...
}
<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>