Validate javascript inside attributes

2019-09-11 04:43发布

问题:

I am using Knockout a lot and often times I have to write scripts inside the data-bind attributes. Is there any validation tools that I can use on these markup files to validate the javascript inside data-bind attributes? Would be nice if there is a grunt plugin.

回答1:

There probably isn't (a prominent) one, because it's not common to have a lot of complex logic inside your view. With MVVM-like approaches it works best if you keep the View rather plain, and write out logic in your ViewModel where you can unit test it.

So do not do this:

var ViewModel = function() {
  var self = this;
  
  self.isCurrent = ko.observable(false);
  self.item = ko.observable({ id: 42 });
}

ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<!-- Don't do this! -->
<div data-bind="visible: !isCurrent() && !!item()">
  Showing something!
</div>

Instead, do this:

var ViewModel = function() {
  var self = this;
  
  self.isCurrent = ko.observable(false);
  self.item = ko.observable({ id: 42 });
  
  self.shouldShowItem = ko.computed(function() {
    return !self.isCurrent() && !!self.item();
  });
}

ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<!-- Don't do this! -->
<div data-bind="visible: shouldShowItem">
  Showing something!
</div>

Because that would allow you to unit test the shouldShowItem logic, e.g. with QUnit:

QUnit.test("shouldShowItem is false if not isCurrent and item not set", function(assert) {
    var vm = new ViewModel();
    vm.isCurrent(false);
    vm.item(null);
    assert.strictEqual(vm.shouldShowItem(), false);
});

Bottom line, if you find yourself writing out lots of logic inside your view, you probably need to move some of it to your view models and make it testable.