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();
})
}