Skip to content

Instantly share code, notes, and snippets.

@jinjor
Last active December 31, 2015 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jinjor/7952359 to your computer and use it in GitHub Desktop.
Save jinjor/7952359 to your computer and use it in GitHub Desktop.

#How to make Hierarchical GUI Components and Applications (1/3)

Original Posts

http://jinjor-labo.hatenablog.com/entry/2013/12/08/221003

http://jinjor-labo.hatenablog.com/entry/2013/12/10/094825

http://jinjor-labo.hatenablog.com/entry/2013/12/12/225955

##Introduction

Recently, many developers try to make rich clinent web applications by means of JavaScript. And they want to make them more smarter ways. and of cource I do too :) I tried many kinds of JavaScript MVC frameworks and finally came to an idea.

Assumptions

  • We wants to make business-like systems.(Not games or web sites)
  • We don't aim to use this idea right now, since we have no sufficeient libraries.

##Constructing UI Components hierarchically

Some libraries like AngularJS or Specifications like Web Components make it possible to define custom elements and use it as same as other HTML elements. Don't you think it a good idea!? Yes, but not so special. It's a common idea for constructing larger things using small parts.

In any case, you like that idea and then try it. The following figure indicates a typical UI which has a selector for something on the left and a viewer showing the details for it on the right.

tree1

Note that this shows not an inheritance relationship but one of posession. Each component has its child components. They must keep ignorant of their neighbors and parents. The higher-located components listen to their chilren's events and then update others. It may be similar if you use jQuery, but the roles of components are much clearer.

##Ok, it's the best practice. Right?

No. It seems to be the best way in most cases, but some more complicated example show the difficalty of applying that simple idea. Here is an example.

tree2

By some serious needs, you have to register persons and calculate the total amount of money they paid.

// イベントを受け取り
var memverView = new MemberView().on("change", updateSubmitView);
memberViewList.add(memverView);

function updateSubmitView(){
    var memberList = memberViewList.map(function(view){
        return view.member;
    });
    submitView.update(memberList);// データを渡す
}

There exist a memberViewList and a submitView in your code. Their roles are carefully separated and the implamentations are encapsulated in case of changing the spec. But the future is always unpredictable. The new spec requires:

  • If a member paid 50% away from the avarage, his view must be colored by red.
  • When at least one such person exists, the submit button must be disabled.

Then the new code is as follows...

var memverView = new MemberView().on("change", updateSubmitView);
memberViewList.add(memverView);

function updateSubmitView(){
    var memberList = memberViewList.map(function(memberView){
        return memberView.member;
    });
    submitView.update(memberList);
    var sum = submitView.getSum();
    memberViewList.forEach(function(memberView){
        memberView.updateBySum(sum);
    });
    var errorFlg = false;
    memberViewList.forEach(function(memberView){
        errorFlg = errorFlg || memberView.getErrorFlg();
    });
    submitView.updateByErrorFlg(errorFlg);
}

What the hell? The data is always comming and going between two views. Do you say that's the OOP way to solve the ploblem?

##Hello, model-driven world.

The worst idea is that each view holds its data respectively, which makes their parent work hard to synchronize their data. Is that mean that separating components is evil? No, but there are some ways to share the single Model by multi Views. The abstraction of this idea is as follows.

tree3

The Views subscribe the change of Model and update themselves. This behavior is common of other nodes of the whole tree. My ideal world works like that.

Next: How to implement this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment