用模型剔除计算列

时间:2019-01-24 15:34:27

标签: javascript c# knockout.js knockout-mvc

我的MVC C#解决方案中有一个具有以下属性的模型

WebElement

在我的JavaScript中,我可以调用模型并显示数据,但是在使用某些计算函数失败的地方。

JavaScript

driver.findElement

HTML

public class RegistrationRequirementModel
{
    public string LoadIntent { get; set; }
    public string Francophone { get; set; }
    public string Gender { get; set; }

    public RegistrationRequirementModel(L09RegistrationRequirement requirement)
    {
        LoadIntent = requirement.LoadIntent;
        Francophone = requirement.Francophone;
        Gender = requirement.Gender;
    }
}

目的是在缺少数据时显示html。但是,当我激活此代码时,计算列始终说frenchData不是函数。我的观点将可以在我的html var registrationRequirementModel = { frenchData: ko.observable(""), genderData: ko.observable(""), loadIntentData: ko.observable(""), isMissingData: ko.computed(function () { if (this.frenchData() == "") { return true }; if (this.genderData() == "") { return true }; if (this.loadIntentData() == "") { return true }; return false; },this), } $(document).ready(function () { ko.applyBindings(registrationRequirementModel, document.getElementById("RegistrationSurveyContent")); $.ajax({ url: getStudentRegRequirementsUrl, type: "GET", contentType: jsonContentType, dataType: "json", success: function (data) { if (!account.handleInvalidSessionResponse(data)) { registrationRequirementModel.frenchData(data.Francophone); registrationRequirementModel.genderData(data.Gender); registrationRequirementModel.loadIntentData(data.LoadIntent); } }, error: function (jqXHR, textStatus, errorThrown) { if (jqXHR.status != 0) $('#notificationHost').notificationCenter('addNotification', { message: "Unable to retrieve registration requirement.", type: "error" }); } }); }); 中使用。但不幸的是。我可以从数据中读取事件。

这是我对api的调用

<table style="width:100%">
    <tbody>
        <tr>
            <td data-bind="text: loadIntentData"></td>
            <td data-bind="text: frenchData"></td>
            <td data-bind="text: genderData"></td>
        </tr>
    </tbody>
</table>

2 个答案:

答案 0 :(得分:1)

frenchData is not a function控制台错误源于KnockoutJS ViewModel的设置方式。本质上,正常可观察对象下方的计算函数isMissingData具有this的新内部作用域上下文,它不能反映registrationRequirementModel对象的相同外部作用域。

enter image description here

要解决此问题,您应该从使用object literal切换到constructor function,以便可以将this ViewModel范围分配给self/that变量,以减轻范围问题。然后通过KO Apply Bindings实例化新存储的ViewModel,在AJAX成功后,您现在将可以访问它:

function registrationRequirementModel() {
  var self = this;
  self.frenchData = ko.observable("");
  self.genderData = ko.observable("");
  self.loadIntentData = ko.observable("");

  self.isMissingData = ko.computed(function() {
    if (self.frenchData() == "") {
      return true
    };
    if (self.genderData() == "") {
      return true
    };
    if (self.loadIntentData() == "") {
      return true
    };
    return false;
  }, this);
}

$(document).ready(function() {
  var vm = new registrationRequirementModel();
  ko.applyBindings(vm, document.getElementById("RegistrationSurveyContent"));

  // replace with endpoint
  var jsonData = {
    Francophone: "Francophone",
    Gender: "Male",
    LoadIntent: "LoadIntent"
  };

  if (handleInvalidSessionResponse(jsonData)) {
    vm.frenchData(jsonData.Francophone);
    vm.genderData(jsonData.Gender);
    vm.loadIntentData(jsonData.LoadIntent);
  }
});

function handleInvalidSessionResponse(data) {
  if (typeof data !== "undefined") return true;
  return false;
}

下面是该场景的模拟JSFiddle http://jsfiddle.net/ajxrw39m/3/

答案 1 :(得分:0)

在定义视图模型时,this并不指向新创建的对象,而是指向您正在创建它的上下文中的任何this(可能是window )。

var vm = {
  computedUsingThis: ko.computed(function() {
    return this;
  }, this)
}

console.log(
  vm.computedUsingThis() === vm,     // false
  vm.computedUsingThis() === window  // true
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

有很多方法可以解决此问题。您可以使用构造函数和new关键字,也可以为viewmodel创建工厂方法:

const VM = () => {
  const a = ko.observable("a");
  const b = ko.observable("b");
  
  const ab = ko.pureComputed(
    () => a() + b()
  );
  
  return { a, b, ab };
}

const vm = VM();
vm.ab.subscribe(console.log);

setTimeout(
  () => {
    vm.a("A");
  },
  500
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>