Javascript 使用自定义指令时,双向绑定在AngularJS中无法立即工作

Javascript 使用自定义指令时,双向绑定在AngularJS中无法立即工作,javascript,angularjs,angularjs-directive,angularjs-scope,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,Angularjs Ng Repeat,我有一个简单的自动完成下拉列表。当我只使用控制器时,它工作正常 我想让它可重用,所以我用独立的作用域制定了一个自定义指令 但问题是,当我在搜索文本框中键入时,它不会立即调用分配给ng change的控制器函数。当我再次开始输入时,它调用函数。同样,它接受我之前键入的值,而不是当前模型值 我是新的自定义指令。。。我真的不知道如何立即更新模型并从指令范围传递到控制器范围 另一个想法是,我无法将函数参数从html传递到控制器函数 我想我必须在某个地方使用$apply或$digest但是我应该在哪里以及

我有一个简单的自动完成下拉列表。当我只使用控制器时,它工作正常

我想让它可重用,所以我用独立的作用域制定了一个自定义指令

但问题是,当我在搜索文本框中键入时,它不会立即调用分配给
ng change
的控制器函数。当我再次开始输入时,它调用函数。同样,它接受我之前键入的值,而不是当前模型值

我是新的自定义指令。。。我真的不知道如何立即更新模型并从指令范围传递到控制器范围

另一个想法是,我无法将函数参数从html传递到控制器函数

我想我必须在某个地方使用
$apply
$digest
但是我应该在哪里以及如何使用?

autofillApp.directive('autofillDropdown', function($rootScope) {

    return {

        restrict: 'A',
        templateUrl: "dropdowntemplate.html",
        replace: true,
        scope: {
            'items': '=autofillItems',
            'selected': '=autofillSelected',
            'change': '&autofillChange',
            'focused': '=autofillFocus',
            'onSelect': '&autofillOnselect'
        },
        link: function(scope, element, attr) {
            //console.log(scope.$$watchers);
            //console.log(element);
            //console.log(attr);
            return
        },
        compile: function(element, attributes) {

            var linkFunction = function($scope, element, attributes) {
                $scope.$apply();
            }
            return linkFunction;
        }

    };
})
这是我的建议:

嘿,我检查了你的方法并解决了你的问题

使用输入字段的“ng change”调用“change”函数。没关系,对。但ng模型目前没有更新。因此,只需提供一个带有输入值的参数

ng-change="change({searchText:selected})"
您需要提供具有正确属性名称的JSON对象。在本例中,我们路由出隔离的作用域,因此需要以这种方式调用它(使用相同的属性名称“searchText”):

因此,最终的“更改”函数应如下所示:

$scope.SearchCurrencyOnSearchTextChange = function (searchText) {
    if (searchText === null || searchText === '' ||searchText ===undefined) {
        $scope.IsFocused = false;
    }
    else {
        $scope.IsFocused = true;
        $scope.searchCurrencies = $scope.GetFilteredData(searchText);
    }
};
我还删除了一些css隐藏和显示方法。如果您使用ng show和jquery显示/隐藏内容,它很快就会让您大吃一惊。试着坚持一个

我还将您的指令从“属性”更改为“元素”指令;D


我尝试将模板和控制器移动到您的指令中,以便您可以重用它。我为分配给controllerAs属性的ViewModel创建了控制器别名。希望这有助于引导您走向正确的方向:

// Main App
var app = angular.module("app", ['autofillApp']);

app.controller("appCtrl", function ($scope, $http) {
    // Main app controller.
});


//Directive App.........................
var autofillApp = angular.module('autofillApp', []);

autofillApp.directive('autofillDropdown',function(){


    var AutoFillCtrl = function() {

      var vm = this;

      // Get autofill data for country...
    vm.SearchCurrencyOnSearchTextChange = function () {
        if (vm.searchTextCurrency === null || vm.searchTextCurrency === '' || vm.searchTextCurrency ===undefined) {
            vm.IsFocused = false;
            document.getElementById('currencySearchList').style.display = "none";
        }
        else {
            vm.IsFocused = true;
            document.getElementById('currencySearchList').style.display = "block";

            vm.SearchCurrencies = vm.GetFilteredData(vm.searchTextCurrency);
        }
    };

    //Get autofill Result on search for Currency
    vm.AutoFillCurrency = function (currency) {
        vm.IsFocused = false;
        document.getElementById('currencySearchList').style.display = "none";
        vm.searchTextCurrency = currency.Name;
    };

    vm.data = [

        {
            Id: 1,
            Name:"Dollar"
        },
        {
            Id: 2,
            Name: "Pound"
        },
        {
            Id: 3,
            Name: "Rupee"
        },
        {
            Id: 4,
            Name: "Yan"
        },

    ];

    vm.GetFilteredData = function (name) {
        var filteredItems = [];
        name = name.toLowerCase();
        for (var i = 0; i < vm.data.length; i++) {
            var result = vm.data[i].Name.toLowerCase().search(name);
            if (result != -1) {
                filteredItems.push(vm.data[i]);
            }
        }

        return filteredItems;
    };

    };

    AutoFillTmpl = '<div class="pos_Rel"><input placeholder="Search Currency e.g. dollar,pound,rupee" type="text" ng-change="vm.change()" ng-model="selected" class="form-control width_full" /><ul ng-show="focused && items" id="currencySearchList"><li class="autofill" ng-repeat="result in vm.items" ng-click="vm.onSelect(result)" ng-bind="result.Name"></li></ul></div>';

    return {

    restrict:'A',
    controller: AutoFillCtrl,
    controllerAs: 'vm',
    bindToController: true,
    template: AutoFillTmpl,
    scope: {
        'items': '=autofillItems',
        'selected': '=autofillSelected',
        'change': '&autofillChange',
        'focused': '=autofillFocus',
        'onSelect': '&autofillOnselect'
    }
};

});
//主应用程序
var-app=angular.module(“app”,['autofillApp']);
app.controller(“appCtrl”,函数($scope,$http){
//主应用程序控制器。
});
//指令应用程序。。。。。。。。。。。。。。。。。。。。。。。。。
var autofillApp=angular.module('autofillApp',[]);
autofillApp.directive('autofillDropdown',function(){
var AutoFillCtrl=函数(){
var vm=这个;
//获取国家/地区的自动填充数据。。。
vm.SearchCurrencyOnSearchTextChange=函数(){
if(vm.searchTextCurrency===null | | vm.searchTextCurrency====''| | vm.searchTextCurrency===未定义){
vm.IsFocused=false;
document.getElementById('currencySearchList').style.display=“无”;
}
否则{
vm.IsFocused=true;
document.getElementById('currencySearchList').style.display=“block”;
vm.searchCurrency=vm.GetFilteredData(vm.searchTextCurrency);
}
};
//在搜索货币时获取自动填充结果
vm.AutoFillCurrency=函数(货币){
vm.IsFocused=false;
document.getElementById('currencySearchList').style.display=“无”;
vm.searchTextCurrency=currency.Name;
};
vm.data=[
{
Id:1,
名称:“美元”
},
{
Id:2,
姓名:“英镑”
},
{
Id:3,
名称:“卢比”
},
{
Id:4,
姓名:“燕”
},
];
vm.getFilteredata=函数(名称){
var filteredItems=[];
name=name.toLowerCase();
对于(var i=0;i
这里正在工作,需要添加手表服务

controller: function($scope){
      $scope.$watch("selected", function(newVal, oldVal){
        $scope.change();
      })
    }

嗯。它正在工作..谢谢。我接受walki12的答案作为批准的答案,因为他还提供了如何从函数传递参数的解决方案……)工作正常。感谢您提供完整的解决方案。
controller: function($scope){
      $scope.$watch("selected", function(newVal, oldVal){
        $scope.change();
      })
    }