All Projects → foo123 → Modelview.js

foo123 / Modelview.js

modelview.js: simple, fast, extendable and isomorphic mv* (mvvm) framework (plays nicely with jQuery)

Programming Languages

javascript
184084 projects - #8 most used programming language

Labels

Projects that are alternatives of or similar to Modelview.js

Iosdesignpatternsamples
This is Github user search demo app which made by many variety of design patterns. You can compare differences in MVC, MVP, MVVM and Flux.
Stars: ✭ 622 (+3558.82%)
Mutual labels:  mvvm
Jetpack Mvvm Best Practice
是 难得一见 的 Jetpack MVVM 最佳实践!在 以简驭繁 的代码中,对 视图控制器 乃至 标准化开发模式 形成正确、深入的理解!
Stars: ✭ 6,950 (+40782.35%)
Mutual labels:  mvvm
Csgo Demos Manager
Stars: ✭ 782 (+4500%)
Mutual labels:  mvvm
T Mvvm
This repository contains a detailed sample app that implements MVVM architecture using LiveData,ViewModel,Retrofit,Rxjava
Stars: ✭ 630 (+3605.88%)
Mutual labels:  mvvm
Stylet
A very lightweight but powerful ViewModel-First MVVM framework for WPF for .NET Framework and .NET Core, inspired by Caliburn.Micro.
Stars: ✭ 665 (+3811.76%)
Mutual labels:  mvvm
Awesome Android Learning Resources
👓 A curated list of awesome android learning resources for android app developers.
Stars: ✭ 753 (+4329.41%)
Mutual labels:  mvvm
Countries
An example Android app using Retrofit, Realm, Parceler, Dagger and the MVVM pattern with the data binding lib.
Stars: ✭ 616 (+3523.53%)
Mutual labels:  mvvm
Marvelheroes
❤️ A sample Marvel heroes application based on MVVM (ViewModel, Coroutines, LiveData, Room, Repository, Koin) architecture.
Stars: ✭ 826 (+4758.82%)
Mutual labels:  mvvm
Devutils
🔥 ( 持续更新,目前含 160+ 工具类 ) DevUtils 是一个 Android 工具库,主要根据不同功能模块,封装快捷使用的工具类及 API 方法调用。该项目尽可能的便于开发人员,快捷、高效开发安全可靠的项目。
Stars: ✭ 680 (+3900%)
Mutual labels:  mvvm
Mvvmhabit
goldze: 本人喜欢尝试新的技术,以后发现有好用的东西,我将会在企业项目中实战,没有问题了就会把它引入到MVVMHabit中,一直维护着这套框架,谢谢各位朋友的支持。如果觉得这套框架不错的话,麻烦点个 star,你的支持则是我前进的动力!
Stars: ✭ 6,789 (+39835.29%)
Mutual labels:  mvvm
Offlinesampleapp
Sample Offline-First MVVM app that uses Android Priority Job Queue, Room, Retrofit2, LiveData, LifecycleObserver, RxJava2, Dagger Android
Stars: ✭ 653 (+3741.18%)
Mutual labels:  mvvm
Tyto
manage and organise things
Stars: ✭ 662 (+3794.12%)
Mutual labels:  mvvm
Ios Clean Architecture Mvvm
Template iOS app using Clean Architecture and MVVM. Includes DIContainer, FlowCoordinator, DTO, Response Caching and one of the views in SwiftUI
Stars: ✭ 753 (+4329.41%)
Mutual labels:  mvvm
Reactive Mvvm Android
My way to MVVM using KotlinX Coroutines and Android data-binding
Stars: ✭ 626 (+3582.35%)
Mutual labels:  mvvm
Loxodon Framework
An MVVM & Databinding framework that can use C# and Lua to develop games
Stars: ✭ 802 (+4617.65%)
Mutual labels:  mvvm
Catel
An application development platform
Stars: ✭ 616 (+3523.53%)
Mutual labels:  mvvm
Ribs
Uber's cross-platform mobile architecture framework.
Stars: ✭ 6,641 (+38964.71%)
Mutual labels:  mvvm
Peopleinspace
Minimal Kotlin Multiplatform project using Jetpack Compose and SwiftUI
Stars: ✭ 887 (+5117.65%)
Mutual labels:  mvvm
Androidviewmodel
Separating data and state handling from Fragments or Activities without lots of boilerplate-code.
Stars: ✭ 824 (+4747.06%)
Mutual labels:  mvvm
Reactiveui
An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms that is inspired by functional reactive programming. ReactiveUI allows you to abstract mutable state away from your user interfaces, express the idea around a feature in one readable place and improve the testability of your application.
Stars: ✭ 6,709 (+39364.71%)
Mutual labels:  mvvm

modelview.js

A simple / extendable / isomorphic / umd-compatible / light-weight (~58kB minified, ~19kB gzipped) mv* (MVVM) framework (plays nicely with jQuery / jQueryUI as plugin / widget as easily)

Version 0.80.0 modelview.js, modelview.min.js, modelview.bundle.js

NEW: ModelView (version 0.60+) is now an (full) isomorphic MVVM framework!

see also:

  • Importer simple class & dependency manager and loader for PHP, Node/XPCOM/JS, Python
  • PublishSubscribe a simple and flexible publish-subscribe pattern implementation for Node/XPCOM/JS, PHP, Python, ActionScript
  • Dromeo a flexible, agnostic router for Node/XPCOM/JS, PHP, Python, ActionScript
  • Dialect a simple cross-platform SQL construction for PHP, Python, Node/XPCOM/JS, ActionScript
  • Xpresion a simple and flexible eXpression parser engine (with custom functions and variables support) for PHP, Python, Node/XPVOM/JS, ActionScript
  • Contemplate a fast, flexible & light-weight template engine for Node/XPCOM/JS, PHP, Python, ActionScript
  • HtmlWidget html widgets used as (template) plugins and/or standalone for PHP, Node/XPCOM/JS, Python (can be used as plugins for Contemplate engine as well)
  • Tao a simple, tiny, isomorphic, precise and fast template engine for handling both string and live dom based templates
  • ModelView MVC jQueryUI Widgets plug-n-play, state-full, full-MVC widgets for jQueryUI using modelview.js (e.g calendars, datepickers, colorpickers, tables/grids, etc..) (in progress)
  • Regex Analyzer/Composer Regular Expression Analyzer and Composer for Node/XPCOM/JS, PHP, Python, ActionScript
  • Abacus a fast combinatorics and computation library for Node/XPCOM/JS, PHP, Python, ActionScript
  • Asynchronous a simple manager for async, linearised, parallelised, interleaved and sequential tasks for JavaScript

Contents

Hello Earth

See it

<div id="screen">
    Hello $(model.msg) &nbsp;&nbsp;(updated live on <i>change</i>)
    <br /><br />
    <input type="text" name="model[msg]" size="50" value="" />
    <button class="button" title="$(model.msg)" data-bind='{"click":"alert_msg"}'>Hello</button>
    <button class="button" data-bind='{"set":{"key":"msg","value":"You"}}'>Hello You</button>
    <button class="button" data-bind='{"click":"hello_world"}'>Hello World</button>
</div>
// standalone

new ModelView.View(
    'view', 
    new ModelView.Model(
        'model', 
        // model data here ..
        { msg: 'Earth!' }
    )
    // model data type-casters (if any) here ..
    .types({ msg: ModelView.Type.Cast.STR })
    // model data validators (if any) here ..
    .validators({ msg: ModelView.Validation.Validate.NOT_EMPTY })
)
.shortcuts({
    'alt+h': 'alert_msg'
})
.actions({
    // custom view actions (if any) here ..
    alert_msg: function( evt, el, bindData ) {
        alert( this.$model.get('msg') );
        // this also works
        //alert( this.model().get('msg') );
        // or even this, if you want the raw data without any processing
        //alert( this.$model.$data.msg );
    },
    hello_world: function( evt, el, bindData ) {
        // set msg to "World" and publish the change
        this.$model.set('msg', "World", true);
    }
})
.attribute( 'bind', 'data-bind' ) // default
.livebind( '$(__MODEL__.__KEY__)' )
.autobind( true )
.isomorphic( false ) // default
.bind( [ 'change', 'click' ], document.getElementById('screen') )
.sync( )
;
// as a jQuery plugin/widget

// make sure the modelview jQuery plugin is added if not already
if ( ModelView.jquery ) ModelView.jquery( $ );
$('#screen').modelview({
    id: 'view',
    
    bindAttribute: 'data-bind', // default
    events: [ 'change', 'click' ], // default
    livebind: '$(__MODEL__.__KEY__)',
    autobind: true,
    isomorphic: false, // default
    autoSync: true, // default
    
    model: {
        id: 'model',
        
        data: {
            // model data here ..
            msg: 'Earth!'
        },
        
        types: {
            // model data type-casters (if any) here ..
            msg: ModelView.Type.Cast.STR
        },
        
        validators: {
            // model data validators (if any) here ..
            msg: ModelView.Validation.Validate.NOT_EMPTY
        }
    },
    
    shortcuts: {
        'alt+h': 'alert_msg'
    },
    
    actions: {
        // custom view actions (if any) here ..
        alert_msg: function( evt, el, bindData ) {
            alert( this.$model.get('msg') );
            // this also works
            //alert( this.model().get('msg') );
            // or even this, if you want the raw data without any processing
            //alert( this.$model.$data.msg );
        },
        hello_world: function( evt, el, bindData ) {
            // set msg to "World" and publish the change
            this.$model.set('msg', "World", true);
        }
    }
});

Browser Support

for ModelView <= 0.26 (using jQuery) browser support is same as basic jQuery support

for ModelView 0.30+ (using native)

  • Firefox 4+
  • Chrome 4+
  • Opera 10+
  • IE 9+

Live Examples

ModelView Temperature example on jsfiddle based on the example post Two Way Data Binding

ModelView TodoMVC example (with routing and localStorage support)

ModelView TodoMVC

MV* Patterns and MVVM

MV Patterns*

MV* (MVC, MVP, MVVM, etc..) patterns were inspired by and developed for use in Graphical User Interfaces. Graphical User Interfaces are asynchronous and can be complex. In sequential/procedural code (which mostly runs synchronously or parallel), the program state is relatively constant and can be managed procedurally more easily.

However for GUI development, the asynchronous and relatively complex (user-defined) interactions (frequently) cause the sequential/procedural approach to become "spaghetti". As a matter of fact both Object-Oriented Paradigm and various Design Patterns around that paradigm (of which MVC is one) were triggered (pun intended) by GUI development issues.

MVC is a pattern for separating presentation from underlying data and logic in a clean, maintainable, way with minimum coupling and dependencies between modules / components. A way for minimum coupling to be implemented is Design-by-Contract , or Design-by-Interface , meaning modules define interfaces of input / output mappings and not specific implementations (which can vary accross both time and space). Additionaly the Chain-of-Responsibility or Publish/Subscribe or Observer patterns are used in order to further minify inter-dependencies and allow multiple participants to receive / respond to events and event flow between modules. Furthermore MVC is (in most implementations) an Inversion of Control (IoC) design pattern.

One of the defining features of MVC is that the same data (model) can be viewed in many different ways (views), or in other words, the same data can be colored in multiple ways , and this connection can also be done in various ways (controllers). In fact models should not care about views and vice-versa (same model can be used with multiple different views and also same view can display multiple different models). Models should be View-agnostic and Views should be Model-agnostic (should not assume too much, apart the needed input/output interfaces)

The M (model) part handles the data and various operations that relate to this data (eg types, valid values, etc).

The V (view) part handles the presentation of given data. What the user actually sees and interacts with.

The C (controller) part handles the connection and event flow between a view and a model.

MVVM is a variation of MVC, where C is replaced by VM (viewmodel).

In MVC the view is usually procedurally generated in code (eg. a Java Swing View), whereas in MVVM the view is declaratively built (eg. markup). Thus the MVVM Controller is not an exact counterpart of an MVC Controller (at least in some implementations).

The ViewModel controller binds a model to a specific (declarative) ui-view. Which brings the next topic, Declarative Data Bindings and MVVM for HTML and JavaScript.

Declarative Data Bindings

Declarative Data Bindings are a way to define in the markup how a specific ui element relates (binds) to the underlying model and logic.

Ok, so why is it good to mix logic and markup (again) after so much trouble for clean separation of markup and logic??

This is a good question and will attempt an answer.

Why is this:

<div data-bind='{"click":"openPopup"}' class="button"></div>

Better than this:

<div onclick="openPopup(this)" class="button"></div>

and why should a designer (who designs the UI) be involved in this??

Answer

  1. True, the basic "form" of both examples above is the same, adding an action to an event directly on the element markup (leave aside the fact that giants like Google Angular use same form).

  2. The first example (although relevant to modelview.js) is more generic than the javascript handler added directly on the element in the second example. The reason is twofold, first more events (even other click events) can still be added to the element unlike the direct handler case. Also there is not actual javascript code, just an identifier of a behaviour (an action in this case) and when (event type) this should be triggered.

  3. A designer has much to say about how the markup element binds and behaves. The simplest answer is that markup elements that are clicked (a behaviour issue) can have different design (css/markup etc..) than markup elements that are just hovered (a design issue). So the designer may be more relevant to declare the data-binding for the event type and behaviour identifier (which requires no extra knowledge of the implementation/logic of the behaviour, how the action is going to be implemented). Consider the following:

<div class="ui-button"></div>
$('.ui-button').button( );

This can be seen as (behavioral) "data-binding", since the "class" assigned to the element, defines how it is going to be rendered and interacted with (it becomes a UIButton in the code logic). The designer need not be concerned about the implementation of the UIButton, but the designer knows that this is a button eventually (it is going to be clicked) and is designed with that in mind.

Arguably declarative (two-way) data bindings are the closest thing (at present) to dynamic (interactive) markup design. Meaning markup that defines apart from static attributes, dynamic behavioral attributes, (sth i find conceptually clean) see also the readme at components.css about declarative over procedural separation of concerns and modularity.

Specificaly for HTML and Javascript, the MVVM pattern has this association related to the MVC pattern:

MVC MVVM
Model: actual data Model: actual data
View: procedurally generated / templates UI(View): actual markup UI (with declarative data bindings) / templates
Controller: binds View to Model ViewModel: binds UI (view) to Model

ModelView.js

ModelView.js is an attempt at using sth like the MVVM pattern in a light-weight, yet extendable and generic way. Inspired mainly by Knockoutjs, Agility and Backbone.js, it is an attempt to combine certain things without repeating everything for some custom projects that can greatly benefit from such an approach.

modelview.js uses JSON format for declarative data binding which is relevant to web (and not only) development. Also modelview.js does not implement every possible interaction and action (some default actions are implemented nevertheless), but can easily define new subclasses of both model and view to have more functionality out of the box.

Current work is focusing on (model) collections and using the composite pattern to define composite models and composite views (which can contain submodels and subviews). This way more complexity (especially collections of objects) can be handled in a more abstract, clean and generic way. Apart from that, current work extends the type-casting, validation framework in an algebraic/functional way, which makes more intuitive and easier to apply types and validation to model data, see examples and updates.

Furthermore, focus is on inline dynamic binding and update directly inside the markup handled by modelview.js (this is sth that is already handled using 'data-bind: text' attributes, however it can become cumbersome), see examples and updates.

jQuery DOM/Event dependency has been removed, ModelView can be used as standalone framework, however it provides a plugin (and widget) for jQuery (jQueryUI) for easy integration (see examples).

Performance

Some tests on jsperf with ModelView, latest backbonejs, knockoutjs and emberJS (on models get/set).

Some notes. The frameworks tested solve different problems so the comparison is only illustrative. The tests use two get operations and one set operation on a single key. ModelView get/set operations are complex operations supporting nested keys (which Ember, Backbone and Knockout do not support by default), custom getters/setters, type-casting and validation. Moreover, modelview set operation, is in general faster than other approaches, while get operation was slowest. To fix this, some minor optimisations were made (see changelog) for get (and set) when just single key is used and the final performance was greatly increased (mostly for get operation which was slower, while get is trivial in other approaches).

Previous tests are here jsperf/0.24, jsperf/0.25, jsperf/0.26, jsperf/0.26 rev2,jsperf/0.26.1, jsperf/0.43, jsperf/0.51

ModelView 0.51 is (consistently) 2nd place (near 1st place) on all browsers (even when using type-caster).

jsperf-model-getset

Some tests on jsperf with ModelView, latest Angular and Knockout on live DOM update and (multiple) watchers/subscribers.

Previous tests are here jsperf/0.42.2, jsperf/0.42.2 variation, jsperf/0.43, jsperf/0.51, jsperf/0.60, jsperf/0.64

ModelView 0.64 is (consistently) 1st place on almost all browsers.

jsperf-angular-knockout-modelview

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].