我有一个编辑框,定义如下:
<input class="change-handled form-control" type-id="@sub.CategoryTypeId" sub-category-id="@sub.SubCategoryId" data-id="@sub.CategoryBudgetId" style="text-align: right; width: 100%" type="number" value="@(sub.BudgetAmount.HasValue ? sub.BudgetAmount.ToString() : "")" />
在Javascript中,我成功获得了data-id值:
var dataId = $(this).attr('data-id');
我现在需要将其设置为不同的值。我在尝试:
$(this).setAttribute("data-id", 5);
但似乎data-id永远不会被设置为我传递的值。如何设置编辑框的data-id值?
正在使用的函数的完整代码。 (注意,还没有错误检查):
$('body').on('change', 'input.change-handled', UpdateTotals);
function UpdateTotals() {
var dataId = $(this).attr('data-id');
var categoryId = $(this).attr('sub-category-id');
var value = $(this).val();
var totalExp = 0;
var totalInc = 0;
var $changeInputs = $('input.change-handled');
$changeInputs.each(function (idx, el) {
if ($(el).attr('type-id') == 2) {
totalInc += Number($(el).val());
}
if ($(el).attr('type-id') == 1) {
totalExp += Number($(el).val());
}
});
$(this).val(numberWithCommas(value));
$('#budgettedExpenseValue').text(numberWithCommas(totalExp));
$('#budgettedIncomeValue').text(numberWithCommas(totalInc));
$('#budgettedAvailableValue').text(numberWithCommas(totalInc - totalExp));
$.ajax({
url: '@Url.Action("SaveBudgetValue", "Budget")',
type: "POST",
contentType: "application/json",
data: JSON.stringify({ budgetCategoryId: dataId, catgoryId: categoryId, month: 4, year: 2015, value: value }),
cache: false,
async: true,
success: function (result) {
if (result.Success == 'true') {
$(this).attr("data-id", result.Id);
alert("Saved! " + result.Id.toString());
} else {
alert("Failed");
}
},
error: function () {
alert("Oh no...");
}
});
在编辑类类型的编辑框之后,代码汇总所有收入框(使用type-id = 1进行装饰),并更新字段和所有费用框(type-id = 2 )并更新一个单独的字段。
然后通过json调用保存数据到我的控制器。如果它是一个新条目,则data-id将为NULL。 save方法返回保存值的主键。该值显示在我的警报中,并且应该被分配给编辑框的数据ID。但是 - 不是。
答案 0 :(得分:3)
重新更新
问题是在ajax
成功回调中,this
不再引用该元素。
解决这个问题的两种方法,以及ES6中可用的第三种方式:
将this
或更有用的$(this)
分配给您在成功处理程序中使用的变量(以及其他地方,无需经常在其上重复调用$()
元素):
function UpdateTotals() {
var input = $(this); // <========== Save it here
// ...
$.ajax({
// ...
success: function (result) {
// ...
if (result.Success == 'true') {
input.attr("data-id", result.Id); // <========= Use it here
alert("Saved! " + result.Id.toString());
} else {
alert("Failed");
}
}
});
// ...
}
使用Function#bind
(ES5功能,但可以为真正的旧浏览器填充),使回调中的this
与其外的this
相同:
function UpdateTotals() {
// ...
$.ajax({
// ...
success: function (result) {
// ...
if (result.Success == 'true') {
$(this).attr("data-id", result.Id);
alert("Saved! " + result.Id.toString());
} else {
alert("Failed");
}
}.bind(this) // <=========== Note
});
// ...
}
在ES6中,我们将有箭头函数,与普通函数不同,它继承了创建它们的上下文的this
。所以在ES6中,你可以这样做:
// **ES6 ONLY**
function UpdateTotals() {
// ...
$.ajax({
// ...
success: (result) => { // <==== Arrow function syntax
// ...
if (result.Success == 'true') {
$(this).attr("data-id", result.Id);
alert("Saved! " + result.Id.toString());
} else {
alert("Failed");
}
}
});
// ...
}
我倾向于#1,因为你无论如何都要重复$(this)
,所以做var input = $(this);
一次然后再使用{ {1}}。
有关我博客上input
的更多信息:
原始回答更新前:
由于您正在使用jQuery,因此您使用attr
设置了一个属性,如下所示:
this
直播示例:
$(this).attr("data-id", 5);
var input = $("input");
snippet.log("Before: " + input.attr("data-id"));
input.attr("data-id", 5);
snippet.log("After (jQuery): " + input.attr("data-id"));
snippet.log("After (DOM): " + input[0].getAttribute("data-id"));
snippet.log("Element's HTML (after): " + input[0].outerHTML);
或者您可以直接使用DOM,不将元素包装在jQuery包装器中:
<input class="change-handled form-control" type-id="@sub.CategoryTypeId" sub-category-id="@sub.SubCategoryId" data-id="@sub.CategoryBudgetId" style="text-align: right; width: 100%" type="number" value="@(sub.BudgetAmount.HasValue ? sub.BudgetAmount.ToString() : "")" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
请注意,在任何一种情况下,即使您给出一个数字作为值,该值最终也会成为一个字符串(因为属性只存储字符串)。
你会让人们告诉你使用data
,但this.setAttribute("data-id", 5);
不只是访问data
属性的一种方式,即使有很多人制作那个错误。但可能对您的最终目标有用,具体取决于它是什么。 jQuery data-*
函数管理与元素关联的数据缓存。值data
管理的值{em>已初始化来自data
属性,但data-*
从不将写入data
属性。如果您只是尝试更新属性值,请使用data-*
。如果您正在尝试执行更复杂的操作,并且将值作为属性写回元素并不重要,请查看attr
的文档,看看它是否对您有用。 (一方面,值data
manage可以是除字符串以外的类型。)
答案 1 :(得分:3)
您将代码放在success
函数中,其中this
将是某种jQuery ajax对象,而不是HTML元素。
您需要将this
存储在ajax调用之外的变量中,然后使用该变量。
e.g。
var that = this;
$.ajax({
然后:
setAttribute
是一个DOM方法,而不是jQuery方法。
或者:
$(that).attr("data-id", 5);
或(假设this
是一个Element对象):
that.setAttribute("data-id", 5);