Skip to content

Commit

Permalink
Add let binding
Browse files Browse the repository at this point in the history
  • Loading branch information
mbest committed Nov 20, 2015
1 parent 281e195 commit 509c9ef
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
1 change: 1 addition & 0 deletions build/fragments/source-references.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ knockoutDebugCallback([
'src/binding/defaultBindings/hasfocus.js',
'src/binding/defaultBindings/html.js',
'src/binding/defaultBindings/ifIfnotWith.js',
'src/binding/defaultBindings/let.js',
'src/binding/defaultBindings/options.js',
'src/binding/defaultBindings/selectedOptions.js',
'src/binding/defaultBindings/style.js',
Expand Down
35 changes: 35 additions & 0 deletions spec/defaultBindings/letBehaviors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
describe('Binding: Let', function() {
beforeEach(jasmine.prepareTestNode);

it('Should be able to add custom properties that will be available to all child contexts', function() {
testNode.innerHTML = "<div data-bind=\"let: { '$customProp': 'my value' }\"><div data-bind='with: true'><div data-bind='text: $customProp'></div></div></div>";
ko.applyBindings(null, testNode);
expect(testNode).toContainText("my value");
});

it('Should update all child contexts when custom properties are updated', function() {
var observable = ko.observable(1);
testNode.innerHTML = "<div data-bind='let: { prop1 : prop()*2 }'><div data-bind='text: prop1'></div></div>";
ko.applyBindings({prop: observable}, testNode);
expect(testNode).toContainText("2");

// change observable
observable(2);
expect(testNode).toContainText("4");
});

it('Should update all custom properties when the parent context is updated', function() {
testNode.innerHTML = "<div data-bind='let: {obj1: $data}'><span data-bind='text:obj1.prop1'></span><span data-bind='text:prop2'></span></div>";
var vm = ko.observable({prop1: "First ", prop2: "view model"});
ko.applyBindings(vm, testNode);
expect(testNode).toContainText("First view model");

// change view model to new object
vm({prop1: "Second view ", prop2: "model"});
expect(testNode).toContainText("Second view model");

// change it again
vm({prop1: "Third view model", prop2: ""});
expect(testNode).toContainText("Third view model");
});
});
1 change: 1 addition & 0 deletions spec/runner.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<script type="text/javascript" src="defaultBindings/htmlBehaviors.js"></script>
<script type="text/javascript" src="defaultBindings/ifBehaviors.js"></script>
<script type="text/javascript" src="defaultBindings/ifnotBehaviors.js"></script>
<script type="text/javascript" src="defaultBindings/letBehaviors.js"></script>
<script type="text/javascript" src="defaultBindings/optionsBehaviors.js"></script>
<script type="text/javascript" src="defaultBindings/selectedOptionsBehaviors.js"></script>
<script type="text/javascript" src="defaultBindings/styleBehaviors.js"></script>
Expand Down
10 changes: 10 additions & 0 deletions src/binding/defaultBindings/let.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ko.bindingHandlers['let'] = {
'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// Make a modified binding context, with extra properties, and apply it to descendant elements
var innerContext = bindingContext['extend'](valueAccessor);
ko.applyBindingsToDescendants(innerContext, element);

return { 'controlsDescendantBindings': true };
}
};
ko.virtualElements.allowedBindings['let'] = true;

0 comments on commit 509c9ef

Please sign in to comment.