All Projects → grofit → Knockout.merge

grofit / Knockout.merge

Licence: mit
Adds basic merging functionality into knockout js mapping namespace

Programming Languages

javascript
184084 projects - #8 most used programming language

Labels

Projects that are alternatives of or similar to Knockout.merge

Reon
🌀 JSON for React.
Stars: ✭ 10 (-33.33%)
Mutual labels:  json
Geochile
Esta es una api de Geocodificación, para que, con las coordenadas Latitud y Longitud se entregue una lista de ciudades cercanas.
Stars: ✭ 13 (-13.33%)
Mutual labels:  json
Bootstrap
Open Source JS plugins
Stars: ✭ 13 (-13.33%)
Mutual labels:  json
Swiftyjsonaccelerator
macOS app to generate Swift 5 code for models from JSON (with Codeable)
Stars: ✭ 864 (+5660%)
Mutual labels:  json
Html Pdf Service
LGPL V3. Java Spring Boot microservice with RESTful webconsole and service endpoints that convert HTML to PDF, optionally styling with CSS and templating with JSON using Flying Saucer, PDF Box and Jackson libraries. Available on Docker Hub.
Stars: ✭ 12 (-20%)
Mutual labels:  json
Esp8266 Wifi Relay
simple sketch of using ESP8266WebServer to switch relays on GPIO pins. It serves a simple website with toggle buttons for each relay
Stars: ✭ 13 (-13.33%)
Mutual labels:  json
Realm.json.extensions
Extension Methods for adding JSON APIs to a Realm Instance
Stars: ✭ 9 (-40%)
Mutual labels:  json
Spimedb
EXPLORE & EDIT REALITY
Stars: ✭ 14 (-6.67%)
Mutual labels:  json
Jogo
JSON o Golang | Forget static types, No more complex structure definitions, Focus on code. Go Reflect!
Stars: ✭ 13 (-13.33%)
Mutual labels:  json
Rest Api Examples
Test and Prototype with Fake Online REST/OAuth 2 APIs Examples
Stars: ✭ 13 (-13.33%)
Mutual labels:  json
Javascript ninja
javascript-ninja 😆
Stars: ✭ 11 (-26.67%)
Mutual labels:  json
Lib
single header libraries for C/C++
Stars: ✭ 866 (+5673.33%)
Mutual labels:  json
Clientserverproject
一个C-S模版,该模版由三部分的程序组成,一个服务端运行的程序,一个客户端运行的程序,还有一个公共的组件,实现了基础的账户管理功能,版本控制,软件升级,公告管理,消息群发,共享文件上传下载,批量文件传送功能。具体的操作方法见演示就行。本项目的一个目标是:提供一个基础的中小型系统的C-S框架,客户端有三种模式,无缝集成访问,winform版本,wpf版本,asp.net mvc版本,方便企业进行中小型系统的二次开发和个人学习。同时网络组件方便的支持读写三菱和西门子PLC的数据,详细见Readme
Stars: ✭ 873 (+5720%)
Mutual labels:  json
Instanote
Note keeping done in PHP 5.2 and JSON
Stars: ✭ 11 (-26.67%)
Mutual labels:  json
Spectral
A flexible JSON/YAML linter for creating automated style guides, with baked in support for OpenAPI v2 & v3.
Stars: ✭ 876 (+5740%)
Mutual labels:  json
Proxy Storage
Provides an adapter for storage mechanisms (cookies, localStorage, sessionStorage, memoryStorage) and implements the Web Storage interface
Stars: ✭ 10 (-33.33%)
Mutual labels:  json
Jquery.json Editor
A json editor based on jquery.json-viewer.
Stars: ✭ 13 (-13.33%)
Mutual labels:  json
Treefrog Framework
TreeFrog Framework : High-speed C++ MVC Framework for Web Application
Stars: ✭ 885 (+5800%)
Mutual labels:  json
Pino
🌲 super fast, all natural json logger
Stars: ✭ 8,475 (+56400%)
Mutual labels:  json
Xml Js
Converter utility between XML text and Javascript object / JSON text.
Stars: ✭ 874 (+5726.67%)
Mutual labels:  json

Knockout.Merge

A simple addition to to the ko namespace to allow merging data into an existing object.

I was finding working with models which exposed bindings in a nested nature would not cope well with dynamic json data. It was either use the mapping plugin to generate the model which removed the ability to use computed observables without attaching them to the instance or manually writing the mapping logic to map data against a given model.

So this simple plugin was designed to take the effort out of working with external data sources which use some form of model as a contract. It will auto merge any data into the bindings without destroying or replacing any of the underlying objects functions. It works fine with nested objects and complex arrays, just make sure that the names of the json keys match the binding names.

Since version 1.5.0 it also works with knockout-es5 module so you can marge in and it will work on the observable behind the scenes so all your existing functionality (custom rules/methods/constructors) will work with them, although its all optional, if you dont use knockout-es5 then it will just operate as normal.

This can be used in nodejs by using npm install knockout.merge, then just require it after knockout and it will extend the object internally.

BREAKING CHANGE SINCE VERSION 1.4.0

Since version 1.4.0 the dependency on knockout.mapping has been completely removed as it relies upon no functionality from the library it was just in there to make it more familiar to developers. Now it has been moved to its own property upon the knockout object, so now it should be:

ko.merge.fromJS(model, data);

Also the name of the file has been changed to reflect this to now be knockout.merge.js.

BREAKING CHANGE SINCE VERSION 1.3.0

Since version 1.3.0 to improve requirejs and module loading capabilities the merge logic is no longer merged into the knockout.mapping namespace it is now in its own namespace knockout.mapping.merge. This is mainly done because in certain situations you would load knockout.mapping.merge as a module via a resource loader you may have all your objects isolated i.e:

var ko = require("knockout");
ko.mapping = require("knockout.mapping");
ko.mapping = require("knockout.mapping.merge"); // wont work as you overwrite the mapping var

So instead we moved all logic into its own namespace so it should now be:

var ko = require("knockout");
ko.mapping = require("knockout.mapping");
ko.mapping.merge = require("knockout.mapping.merge"); // will work as you are not merging functionality into ko.mapping

Anyway that aside there are now some changes to the method names as it makes no sense to have ko.mapping.merge.mergeFromJs, so it has now been changed to ko.mapping.merge.fromJS and ko.mapping.merge.rules (for your custom rules).

The knockout observable extensions remain unchanged so you wont need to worry about changing any of that stuff.

The examples are all updated to reflect this so check out the source code if you are unsure what I mean.

Finally there is an update to the d.ts file for typescript, which should be compatible with DefinitelyTyped stuff, so just whack it in a folder and feel free to change the references to whatever you want them to be.

Example

A simple example of merging some Json data into an existing model:

function User() {
    var self = this;
    
    self.Firstname = ko.observable();
    self.Surname = ko.observable();
    
    self.Fullname = ko.computed(function() {
        return self.Firstname() + " " + self.Surname();
    });
}

var someJson = {
	Firstname: "James",
	Surname: "Bond"
};

var someUser = new User();
ko.merge.fromJS(someUser, someJson);

// Will output "James Bond"
alert(someUser.Fullname());

This should also solve the problem when using Knockout Validation, as the model remains intact so you can map from json or complex objects without worrying about losing your bindings:

function User() {
    var self = this;
    
	self.Age = ko.observable().extend({ digits: true });
    self.Firstname = ko.observable().extend({ maxLength: 20 });
    self.Surname = ko.observable().extend({ maxLength: 20 });
    
    self.Fullname = ko.computed(function() {
        return self.Firstname() + " " + self.Surname();
    });
}

var someJson = {
	Firstname: "James",
	Surname: "Bond",
	Age: 40
};

var someUser = new User();
ko.merge.fromJS(someUser, someJson);

There is also an option to infer the types for observable arrays so you can just auto-merge array elements into your observables, however this functionality will not be able to distinguish between existing elements and new elements so this will currently just append elements to the array not merge them.

You can do this like this:

function SomeChildModel()
{
   this.Name = ko.observable();
}

function SomeModel()
{
   this.someArray = ko.observableArray().withMergeConstructor(SomeChildModel);
}

There has been some new additions to allow you to write custom merging logic, this is useful for certain situations such as mapping date strings to date objects, or do anything more complicated than a simple data replacement. You can either do this by embedding your own method into the merging logic such as:

function SomeModel()
{
	this.Date = ko.observable(new Date()).withMergeMethod(function(knockoutElement, dataElement, options) {
		knockoutElement(new Date(dataElement));
	});
}

Personally I am not a massive fan of this as you will rarely want to embed your mapping logic into your pojo models, so if you want to use more of an AOP style approach and have your logic elsewhere then use the merging rules style settings:

// This can go anywhere, just make sure you include the required libs first 
ko.merge.mergeRules["Date"] = function(knockoutElement, dataElement, options) {
	knockoutElement(new Date(dataElement));
};

function SomeModel()
{
	this.Date = ko.observable(new Date()).withMergeRule("Date");
}

Global Handlers

In version 1.5.1 you can also use global handlers, which are provided the current elements to see if it can deal with them, in most cases you will not need to use these. However lets imagine you have Date objects in your models and you do not want to have to constantly add .withMergeRule("my-date-rule") you can make a handler to check if it is a date object, and if so do something useful with it. Handlers should return a true if they have handled the data or a false if they are not.

A global handler should be a function taking the knockout element and data element and returning a bool as mentioned above, here is a simple example of one:

var globalDateHandler = function(knockoutElement, dataElement, options) {
    if(knockoutElement() instanceof Date) {
        knockoutElement(new Date(dataElement));
        return true; // We handled it so no need to check with other handling mechanisms
    }
    return false; // It is not a date type, so delegate to normal handlers
}

ko.merge.globalHandlers.push(globalDateHandler);

This is for niche scenarios where you do want to do system wide stuff and remember these global handlers will be iterated over for EVERY entry in the data model, so if you are doing some resource intensive stuff in there expect some slowdown. However in most cases "Fast is fast enough" so I wouldn't worry, and if there are no handlers then the normal merging predicates are used.

You can omit the options, and they are for you to be able to write your own options for passing into rules, however there is one rule the native merge uses mergeMissingAsObservables: true | false, if it is true then if you were to have an empty json containing object, it would end up creating it with observable fields not primitive ones.

Finally there is also a typescript descriptor file available in the source folder to give you compile time safety.

Here is an example of what it does and how to use it, but you will need to check out the source code. View Example

Here are the tests which you can run in your own browser: [View Tests] (https://rawgit.com/grofit/knockout.merge/master/tests/test-runner.html)

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].