Angularjs 选择2、ng型号和角度
使用(notuiselect)和angular,我试图将值设置为ng模型 我尝试过使用Angularjs 选择2、ng型号和角度,angularjs,jquery-select2,angularjs-ng-change,jquery-select2-3,Angularjs,Jquery Select2,Angularjs Ng Change,Jquery Select2 3,使用(notuiselect)和angular,我试图将值设置为ng模型 我尝试过使用$watch和ng change,但在使用select2选择一个项目后,似乎没有一个项目启动 不幸的是,我使用的是购买的模板,无法使用angular ui HTML: <input type="hidden" class="form-control select2remote input-medium" ng-model="contact.person.id" value="{{ cont
$watch
和ng change
,但在使用select2选择一个项目后,似乎没有一个项目启动
不幸的是,我使用的是购买的模板,无法使用angular ui
HTML:
<input type="hidden" class="form-control select2remote input-medium"
ng-model="contact.person.id"
value="{{ contact.person.id }}"
data-display-value="{{ contact.person.name }}"
data-remote-search-url="api_post_person_search"
data-remote-load-url="api_get_person"
ng-change="updatePerson(contact, contact.person)">
$scope.updatePerson = function (contact, person) {
console.log('ng change');
console.log(contact);
console.log(person);
} // not firing
$scope.$watch("client", function () {
console.log($scope.client);
}, true); // not firing either
var handleSelect2RemoteSelection = function () {
if ($().select2) {
var $elements = $('input[type=hidden].select2remote');
$elements.each(function(){
var $this = $(this);
if ($this.data('remote-search-url') && $this.data('remote-load-url')) {
$this.select2({
placeholder: "Select",
allowClear: true,
minimumInputLength: 1,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: Routing.generate($this.data('remote-search-url'), {'_format': 'json'}),
type: 'post',
dataType: 'json',
delay: 250,
data: function (term, page) {
return {
query: term, // search term
};
},
results: function (data, page) { // parse the results into the format expected by Select2.
return {
results: $.map(data, function (datum) {
var result = {
'id': datum.id,
'text': datum.name
};
for (var prop in datum) {
if (datum.hasOwnProperty(prop)) {
result['data-' + prop] = datum[prop];
}
}
return result;
})
}
}
},
initSelection: function (element, callback) {
// the input tag has a value attribute preloaded that points to a preselected movie's id
// this function resolves that id attribute to an object that select2 can render
// using its formatResult renderer - that way the movie name is shown preselected
var id = $(element).val(),
displayValue = $(element).data('display-value');
if (id && id !== "") {
if (displayValue && displayValue !== "") {
callback({'id': $(element).val(), 'text': $(element).data('display-value')});
} else {
$.ajax(Routing.generate($this.data('remote-load-url'), {'id': id, '_format': 'json'}), {
dataType: "json"
}).done(function (data) {
callback({'id': data.id, 'text': data.name});
});
}
}
},
});
}
});
}
};
JQuery集成:
<input type="hidden" class="form-control select2remote input-medium"
ng-model="contact.person.id"
value="{{ contact.person.id }}"
data-display-value="{{ contact.person.name }}"
data-remote-search-url="api_post_person_search"
data-remote-load-url="api_get_person"
ng-change="updatePerson(contact, contact.person)">
$scope.updatePerson = function (contact, person) {
console.log('ng change');
console.log(contact);
console.log(person);
} // not firing
$scope.$watch("client", function () {
console.log($scope.client);
}, true); // not firing either
var handleSelect2RemoteSelection = function () {
if ($().select2) {
var $elements = $('input[type=hidden].select2remote');
$elements.each(function(){
var $this = $(this);
if ($this.data('remote-search-url') && $this.data('remote-load-url')) {
$this.select2({
placeholder: "Select",
allowClear: true,
minimumInputLength: 1,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: Routing.generate($this.data('remote-search-url'), {'_format': 'json'}),
type: 'post',
dataType: 'json',
delay: 250,
data: function (term, page) {
return {
query: term, // search term
};
},
results: function (data, page) { // parse the results into the format expected by Select2.
return {
results: $.map(data, function (datum) {
var result = {
'id': datum.id,
'text': datum.name
};
for (var prop in datum) {
if (datum.hasOwnProperty(prop)) {
result['data-' + prop] = datum[prop];
}
}
return result;
})
}
}
},
initSelection: function (element, callback) {
// the input tag has a value attribute preloaded that points to a preselected movie's id
// this function resolves that id attribute to an object that select2 can render
// using its formatResult renderer - that way the movie name is shown preselected
var id = $(element).val(),
displayValue = $(element).data('display-value');
if (id && id !== "") {
if (displayValue && displayValue !== "") {
callback({'id': $(element).val(), 'text': $(element).data('display-value')});
} else {
$.ajax(Routing.generate($this.data('remote-load-url'), {'id': id, '_format': 'json'}), {
dataType: "json"
}).done(function (data) {
callback({'id': data.id, 'text': data.name});
});
}
}
},
});
}
});
}
};
任何建议都将不胜感激!:)
更新
我已经设法将这两个事件放在一起,这似乎类似地再现了这个问题——现在看来,ng watch和$watch事件似乎只有在第一次更改值时才被触发。
尽管如此,在我的代码中(以及在添加进一步的复杂性时,如动态添加和从集合中删除),它似乎不会触发一次
再次强调,正确方向的指针(或任何方向的指针)将非常感谢 您的示例存在许多问题。我不确定我是否能够提供一个“答案”,但希望下面的建议和解释能帮助你 首先,您正在“混合”jQuery和Angular。一般来说,这真的不起作用。例如: 在script.js中,您可以运行
$(document).ready(function() {
var $elements = $('input[type=hidden].select2remote');
$elements.each(function() {
//...
});
});
这段代码将在DOM初始就绪时运行一次。它将使用select2remote类选择当前在DOM中的隐藏输入元素,并在这些元素上初始化select2插件
问题是,任何新输入[type=hidden].select2remote元素在运行此函数后添加,将不会初始化。例如,如果异步加载数据并填充ng repeat,就会发生这种情况
解决方法是将select2初始化代码移动到一个指令,并将该指令放置在每个输入元素上。简而言之,此指令可能如下所示:
.directive('select2', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ngModel) {
//$this becomes element
element.select2({
//options removed for clarity
});
element.on('change', function() {
console.log('on change event');
var val = $(this).value;
scope.$apply(function(){
//will cause the ng-model to be updated.
ngModel.setViewValue(val);
});
});
ngModel.$render = function() {
//if this is called, the model was changed outside of select, and we need to set the value
//not sure what the select2 api is, but something like:
element.value = ngModel.$viewValue;
}
}
}
});
很抱歉,我对select2不够熟悉,不知道获取和设置控件当前值的API。如果你在评论中提供给我,我可以修改这个例子
您的标记将更改为:
<input select2 type="hidden" class="form-control select2remote input-medium"
ng-model="contact.person.id"
value="{{ contact.person.id }}"
data-display-value="{{ contact.person.name }}"
data-remote-search-url="api_post_person_search"
data-remote-load-url="api_get_person"
ng-change="updatePerson(contact, contact.person)">
这里有两个问题:
首先,您在控制器中使用jQuery,这是不应该做的。其次,这行代码将在控制器启动时DOM中的整个应用程序中的select2remote类的每个元素上触发一个更改事件 通过Angular(即通过ng repeat)添加的元素很可能不会在其上注册更改侦听器,因为它们将在控制器实例化后(在下一个摘要周期)添加到DOM中 此外,控制器作用域之外具有更改事件的元素将修改控制器的$scope的状态。同样,解决方案是将此功能移到指令中,并依赖ng模型功能 请记住,无论何时离开Angular的上下文(即,如果使用jQuery的$.ajax功能),都必须使用scope.$apply()重新输入Angular的执行上下文
我希望这些建议对你有所帮助 您可以共享集成的jquery端吗?我怀疑您需要做更多的工作来处理jquery-select2发出的事件。使用普通JavaScript(或jquery)处理程序并使用
$scope.$apply
,比如$('.select2remote')。on('change',function(){var value=$(this).value;$scope.$apply(function)(){$scope.contact.person.id=value;});})
@JoeEnzmingerupdated@aziumAFAIK$scope在模块外不可供我使用。我错了吗?让我们来看看。这里是select2的api:$(“#select”)。select2(“val”);//获取值$(“#select”)。select2(“val”,“foo”);//设置值,以便在本例中只更改element.value=ngModel.$viewValue by element.select2(“val”,ngModel.$viewValue)在我的情况下,如果选择选项的值与文本(视图值)不同,我必须使用:var newViewValue=$('option:selected',this).text();
范围。$apply(函数(){
ngModel.$setViewValue(newViewValue);
});