-
-
Notifications
You must be signed in to change notification settings - Fork 5
Model
Let's start with this simple element
<sf-m name="something">
<span>{{ text }}</span>
</sf-m>
sf.model.for('something', function(self, other){
// `text` on the DOM element will be filled with `My Name`
self.text = 'My Name';
// Run something after this model was loaded on the DOM
self.init = function(){
// self.$el('.selector');
}
});
sf.model.for('another-thing', function(self, other){
self.stuff = 'Hello world';
});
Binded text node shouldn't be replaced with another one because it will remove the binding feature.
After any element with <sf-m>
tag was inserted into DOM, the related model will have $el
property that contains collection of <sf-m>
elements. This also applies when using component (But only contain one element).
sf.model.for('something', function(self){
self.init = function(){
self.$el('#element').html("Route was finished");
// self.$el.find('#element').html("Route was finished");
}
});
// Or with extend class, component also have this feature
class MyClass{
// will be called when model initialized
// and before calling `self.init`
static construct(){
// this.abc === 1
this.hello = 2;
}
method(){ console.log("1") }
}
sf.model('something', {extend: MyClass}, function(self){
self.abc = 1;
self.init = function(){
// self.hello === 2
// self.method(); (console output -> 1 and 2)
}
self.method = function(){
this.super(/* args */); // can also call parent method
console.log("2");
}
});
Get data from current model scope
{{ model.variable }}
Conditional template
{{@if model.view === true :
{[ <html_content> ]}
@elseif model.view === undefined:
model.data.splice(0);
@else:
{[ <html_content> ]}
}}
As a replacement for <script>
tag. You can also output html by wrap it inside '{[ ... ]}'.
{{@exec javascript stuff}}
All model variable or function can be referenced to the execution scope.
Make sure you write in ES5 because browser doesn't use transpiler.
<sf-m name="something">
<span>{{@exec
for(var i = 0; i < 5; i++){
{[ <label>i -> {{ i }}</label> ]}
}
myAlert("hello");
{[ <br> ]}
// Below will displaying the data without escaping the html
// Always make sure you have secured the output
// And maybe escaping HTML tags
@return number.join(',');
}}</span>
</sf-m>
sf.model.for('something', function(self, other){
self.number = [1, 2, 3, 4, 5];
});
And the HTML output content will be escaped like below
<sf-m name="something">
<span>
<label>i -> 0</label>
<label>i -> 1</label>
<label>i -> 2</label>
<label>i -> 3</label>
<label>i -> 4</label>
<br> 1,2,3,4,5
</span>
</sf-m>
Any {[ inner {{ property }} ]}
will not bind into the model, as an alternative you must define a variable outer of the {[ template ]}
.
<sf-m name="something">
<span>
{{@exec
var bindMe = prefix;
for(var i = 0; i < 5; i++){
{[ <label>i -> {{ bindMe }}</label> ]}
}
}}
</span>
</sf-m>
If you want the framework to parse any custom element (element tag with dashes -
) you need to add sf-parse
to the element attribute.
To enable two-way data binding with input element, you need to set model property in sf-bound
attribute. When you need to obtain multiple value for checkbox
or select
, your model property should be an Array type. But if you like to check if the checkbox is checked
or not, you need to set the model property as Boolean type. Using String data type will only return the last selected data.
<!-- data on the model will be updated if input detected and vice versa -->
<input sf-bind="myInput" type="text" />
<textarea sf-bind="myText" type="text"></textarea>
<input sf-bind="myFiles" type="file" />
<input sf-bind="myRadio" type="radio" value="radio1" />
<input sf-bind="myRadio" type="radio" value="radio2" />
<!-- You can also set property in `name` attribute -->
<input name="myCheckbox" type="checkbox" value="check1" sf-bind />
<input name="myCheckbox" type="checkbox" value="check2" sf-bind />
<select sf-bind="selectInput" typedata="number">
<option value="1">Select 1</option>
<option value="2">Select 2</option>
<option value="3">Select 3</option>
</select>
<select sf-bind="selectInput" multiple>
<option value="{{ x.val }}" sf-repeat-this="x in selectData">
{{ x.text }}
</option>
</select>
To enable one-way data binding with input element, you need to define model property in sf-into
attribute.
<!-- 'myInput' on the model will be updated if input detected -->
<!-- (View -> Model) -->
<input sf-into="myInput" type="text" typedata="number"/>
<!-- input will be updated if 'myInput' on the model was changed -->
<!-- (Model -> Input) -->
<input value="{{myInput}}" type="text" />
<!-- You can also add prefixed value -->
<input value="It's {{myInput}}" type="text" />
<!-- When binding to `class` attribute you need to use `:class` -->
<span :class="icon-{{myInput || 'nothing'}}" style="font-size: {{myInput}}" />
// Model for the above examples
sf.model.for('example', function(self){
// Any input on element will update this content and the binded view
self.myInput = 0;
// Listen any changes before new value assigned to `myInput`
// Useful if you want to process any changes
// Returned value will assigned as new value
self.on$myInput = function(oldValue, newValue){}
// Listen changes (Model -> View)
// Useful to avoid execution when new value was assigned from the view
// Returned value will assigned as new value
self.out$myInput = function(oldValue, newValue){}
// Listen changes (Model -> View)
// This can also being triggered when (View -> [Model -> View])
// Returned value will only change element content
self.m2v$myInput = function(oldValue, newValue){
return formatCurrency(newValue);
}
// Listen changes (View -> Model)
// This will triggered on input/change event
// Returned value will assigned as new value
self.v2m$myInput = function(oldValue, newValue){
console.log("Value will be reverted in 3s to oldValue");
setTimeout(function(){
self.myInput = oldValue;
}, 3000);
}
});
- Framework
-
Installation
- Build Configuration
- Hot Reload
- Loader
- Model
-
Component
- Reserved Element
- Empty Shell
- Include external template
- Space
-
Views (Router)
- URI
- Static Template
- Language
- Element's query helper
- Events
- URL Request
- Window Extends