knockoutjs : valueHasMutated

Explicitly Triggering the Evaluation of Observables with ValueHasMutated

In certain scenarios, you will want to be able to notify the subscribers with the latest value of an observable, You can achieve this by using the valueHasMutated function for any observable.
valueHasMutated is what is used internally to notify when the value has actually changed. However, it can be used to trigger subscribers with the same value.


<button data-bind="click: handleClick">Click me</button>


var viewmodel = function () {
    self.projectsVisible = ko.observable(false);
    self.handleClick = function () {
        self.projectsVisible.valueHasMutated();
    };
    self.projectsVisible.subscribe(function (newValue) { alert(newValue); });
}

ko.applyBindings(viewmodel);

Advertisements

knockoutjs : components

Components are a powerful, clean way of organizing your UI code into self-contained, reusable chunks. This feature allows developer to build some custom UI components that will have it’s own view and logic. You can register a component using ko.components.register (technically, registration is optional, but it’s the easiest way to get started). A component definition specifies a viewModel and template.

  • viewModel is optional
  • template is required

REGISTRATION

ko.components.register('mywidget', {
    viewModel: function(params) {
        //Define view model here
        this.title = ko.observable("I am a Widget");
    },
    template: '</pre>
<div></div>
<pre>'
});

USE


<mywidget></mywidget>

OR

</pre>
<div data-bind="component: {
     name: &quot;mywidget&quot;
}"></div>
<pre>

Example with Backbone


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Home Page</title>
<script type="text/javascript" src="../lib/knockout-3.2.0.debug.js"></script>
<script type="text/javascript" src="../lib/underscore.js"></script>
<script type="text/javascript"
	src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript"
	src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min.js"></script>
<script type="text/javascript" src="../js/demo.js"></script>
</head>
<body>
	<div id="start-div">
		<div id="title-div"></div>
		<div id="my-widget"></div>
	</div>
</body>
</html>

demo.js


$(document).ready(function() {
	var MyView = Backbone.View.extend({
		el : '#start-div',
		render : function() {
			this.$el.find("#title-div").html('Hello Knockout');
			this.koStart();
		},

		koStart : function() {
			this.initKOComponent();
			this.$el.find("#my-widget").append("<mywidget params='titleText: title'></mywidget>");
			
			var viewModel = {
					title : "I am a custom Widget"
				};
			
			ko.applyBindings(viewModel);
		},
		initKOComponent : function() {
			ko.components.register('mywidget', {
				viewModel : function(params) {
					this.widgetTitle = ko.observable(params.titleText);
				},
				template : '<div data-bind="text: widgetTitle"></div>'
			});
		}

	});
	var myView = new MyView();
	myView.render();

});

knockoutjs : “template” binding

  • Rendering a named template
  • If you want to, you can factor out templates into a separate element and then reference them by name:

    
    <h2>Participants</h2>
    Here are the participants:
    <div data-bind="template: { name: 'person-template', data: buyer }"></div>
    <div data-bind="template: { name: 'person-template', data: seller }"></div>
     
    <script type="text/html" id="person-template">
        <h3 data-bind="text: name"></h3>
        <p>Credits: <span data-bind="text: credits"></span></p>
    </script>
     
    <script type="text/javascript">
         function MyViewModel() {
             this.buyer = { name: 'Franklin', credits: 250 };
             this.seller = { name: 'Mario', credits: 5800 };
         }
         ko.applyBindings(new MyViewModel());
    </script>
    
    

    In this example, the person-template markup is used twice: once for buyer, and once for seller. Notice that the template markup is wrapped in a — the dummy type attribute is necessary to ensure that the markup is not executed as JavaScript, and Knockout does not attempt to apply bindings to that markup except when it is being used as a template.

    knockoutjs : Two way data binding with Observables

  • Two way data binding with Observables
  • Change in data will be reflected in change in template
  • <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <title>Home Page</title>
    <script src="../lib/knockout-3.2.0.debug.js" type="text/javascript"></script>
    </head>
    <body>
    	<label>Hello </label>
    	<input type="text" data-bind="value: name" />
    	<script type="text/javascript">
    		// Here's my data model
    		var viewModel = {
    			name : ko.observable("Shiv")
    		};
    		ko.applyBindings(viewModel); // This makes Knockout get to work
    		
    		setTimeout(function(){ viewModel.name("Shivanshu"); }, 3000);// change data after 3 seconds
    		
    	</script>
    </body>
    </html>
    

    ang2

    After 3 seconds…..

    ang3