我已经为angular创建了自定义select2指令,它非常适合我的用例,当我使用模板时,它会像魅力一样设置并从input/ngModel中获取值但是当我在视图页面上使用它时,它不会通过scope解析ngModel。美元eval
这是一个范围问题,请帮助我请参阅以下指示:
(function () {
'use strict';
var directiveId = 'snSelect2';
angular.module('app').directive(directiveId, ['datacontext', snSelect2]);
function snSelect2(datacontext) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, controller) {
var urlPrefix =datacontext.urlPrefix;
$(function () {
element.select2({
placeholder: element.attr('placeholder'),
multiple: angular.isDefined(attrs.multiple),
minimumInputLength: 3,
blurOnChange: true,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: urlPrefix + "/Employees",
dataType: 'json',
data: function (term) {
return {
term: term
};
},
results: function (data) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return { results: data };
}
},
initSelection: function (element, callback) {
var id = scope.$eval(attrs.ngModel);//$(element).val();
if (id != "") {
$.ajax(urlPrefix + "/EmployeeById",
{
data: {
id: id,
format: 'json'
},
datatype: 'json'
}).done(function (data) {
if (angular.isDefined(attrs.multiple)) {
callback(data);
}
else {
callback(data[0]);
}
});
}
//var data = {id: element.val(), text: element.val()};
//callback(data);
},
dropdownCssClass: "bigdrop", // apply css that makes the dropdown taller
escapeMarkup: function (m) { return m; } // we do not want to escape markup since we are displaying html in results
}).select2('val', scope.$eval(attrs.ngModel))
.on("change", function (e) {
scope.$apply(function () {
controller.$setViewValue(attrs.ngModel);
});
});
element.bind("change", function (e) {
scope.$apply(function () {
scope[attrs.ngModel] = e.val;
});
});
});
}
}
}})();
http://snag.gy/lcizI.jpg
<!-- html element -->
<input type="hidden" class="form-control" data-ng-model="show" ui-select2="getShow">
$scope.getShow = {
placeholder: "Enter Show Code",
minimumInputLength: 3,
escapeMarkup: function (m) { return m; },
formatSelection: function(obj, container) {
return "ID: " + obj.showid + " - " + obj.name;
},
formatResult: function(obj, container, query) {
var start = obj.startdate ? moment(obj.startdate).format("DD/MM/YYYY") : "Unknown";
var end = obj.enddate ? moment(obj.enddate).format("DD/MM/YYYY") : "Unknown";
return '<div class="list-group-item small">' +
'<i><span class="label label-default pull-right">ID: ' + obj.showid + '</span></i>' +
'<i><span class="label label-info">(' + obj.code + ')</span></i>' +
'<div style="padding-top: 4px"><strong>' + obj.name + '</strong></div>' +
'<i>' + start + " - " + end + '</i>' +
'</div>';
},
query: function(options) {
if (!options.context)
options.context = {};
// status == processing means http request is in process, so don't do it again
if (options.context.status === "processing")
return;
options.context.status = "processing";
// this is just like ajax $http.get("/search").
model.show.search("search", {code: options.term, limit: 10, sort: 'ts desc'} )
.then(function(result) {
// set status = completed to indicate http request finished.
options.context.status = "completed";
// when you get the result from ajax, callback require you to call with
// an object { results: your result } as result
$scope.list.datalist.show = result;
options.callback({
results: result
});
});
}
}
Data from server looks like
[{
code: "MELCCS"
enddate: "2014-03-10T14:00:00.000Z"
id: "5329c28087b375a4d8a2af43"
name: "Melbourne Caravan and Camping Show"
openinghour: ""
showid: 1810
startdate: "2014-03-05T14:00:00.000Z"
state: "VIC"
status: "Research"
ts: 1395245779280
updatedAt: "2014-03-21T09:16:56.859Z"
warehouse: "52ecd53b673a5fba428e21a7"
}]