Jii allows you to encode models - and their relations - variables (strings, integers, arrays, floats, booleans) and urls into their Javascript equivalents. You can also use Jii to store your Javascript functions without polluting the global scope. Since version 0.0.3beta, Jii allows you to perform some basic operation on Javascript models and introduces some functions to interact with Knockout js observables. The aim of this extensions is to keep your server side code as well as your client side one more maintainable. Moreover it aims to ease the process of sharing data beetween PHP and Javascript.
Requirements ¶
Yii 1.1 or above PHP 5 or above
Configuring Yii ¶
Copy Jii folder to your applications protected/components folder. And add the following lines to your config/main.php.
'components' => array(
...
'jii' => array(
'class' => 'application.components.Jii.Jii',
// uncomment the following
// if you do not want to use the minified version
// 'script' => 'jii-0.0.4.js',
),
...
),
Add Jii to your page ¶
Adding Jii to your page is easy and can be done as follows:
Yii::app()->clientScript->registerScript('jii', Yii::app()->jii->getScript(), CClientScript::POS_END);
Sample usage ¶
You can add params, urls, models and functions to Jii as follows:
// adding params
// you can use any kind of php variable
Yii::app()->jii->addParam('your_param', 10);
// adding urls
Yii::app()->jii->addUrl('view_test_url', $this->createUrl('test/view'));
// adding functions
Yii::app()->jii->addFunction('function', 'function(){
alert("This is an alert!");
}');
Other usage examples ¶
Adding Models to Jii ¶
As regards CActiveRecord instances (or class instances inheriting from CModel), you can select which attribute you want Javascript have access to by adding the following method to each of the CActiveRecord class files you wish to convert ...
...
public function getJsonizeables()
{
return array(
'attribute_label_1',
'attribute_label_3',
'attribute_label_4',
);
}
...
... and then you can use the following code to add it to Jii:
$jsonized_model = Yii::app()->jii->jsonize($model);
// adding models to jii
Yii::app()->jii->addModel('model', $jsonized_model);
Since version 0.0.3beta, Yii::app()->jii->addModel() accepts models and dataproviders as well as jsonized data:
$model = new Model();
Yii::app()->jii->addModel('javascript_model', $model);
Jsonizing CActiveDataProviders ¶
Since jii 0.0.2 you can jsonize CActiveDataProviders as you do with model instances or model arrays:
$jsonized_data_provider = Yii::app()->jii->jsonize($data_provider);
// adding data provider to jii
Yii::app()->jii->addModel('model', $jsonized_data_provider);
Adding binding functions ¶
You can add any function that needs to be executed after the page has finished loading with the following code:
Yii::app()->jii->addBindings('function(){
// the following alert will be shown after
// page has finished loading
alert("Hello world!");
}');
Jsonizing custom attributes ¶
Sometimes you may need to perform additional operation on models' attributes values before passing them to Javascript. In such cases, you can jsonize custom attributes in the following way. Create or add to the model/model's you wish to jsonize the getJsonizeables method and add to the array a custom attribute name such as custom_attribute_1. After that, create a public method named getcustom_attribute_1() which performs some operation over one ore more model attributes and return a value.
...
public function getJsonizeables()
{
return array(
'attribute_label_1',
'attribute_label_3',
'attribute_label_4',
...
'custom_attribute_1',
);
}
// the following method allows you to jsonize custom attributes
public function getCustom_attribute_1()
{
return $this->_performSomeOperation($this->attribute_label_1);
}
...
Javascript Models ¶
Since version 0.0.3beta each Jii model is an object providing the following methods: ~~~ [javascript] /**
- Finds one model instance based on the specified attribute
- @param object {attribute: "attribute_name", value: attribute_value}
- @return object or null if none object is found */ jii.models.javascript_model.findByAttribute();
// the Javascript object representation of a jii Model jii.models.javascript_model.toJS();
// the number of model instances found jii.models.javascript_model.count(); ~~~
Knockout js utilities ¶
Since Jii 0.0.3beta you will have at your disposition a couple of functions: ~~~ [javascript] /**
- Converts a jii model into an Knockout observable
- @param object model
- @return observable */ jii.utils.observable();
// the same as above except that it returns an observable array jii.utils.observableArray(); ~~~
Changelog ¶
2012-12-14 jii 0.0.4
- jii script is added through CClientScript and no longer interferes with PHP code
- jii can be used across the whole page without concurrencies
- Added function bindings
- Fixed some minor bugs
2012-12-13 jii 0.0.3beta
- Some bug fixes
2012-12-12 jii 0.0.3beta
- Knockout js functions
- Direct jsonization of models
- Javascript models functions
2012-12-10 jii 0.0.2
- Jsonizer support for CActiveDataProvider
Resources ¶
- Github project page at: Jii
- Yii forum page at: http://www.yiiframework.com/forum/index.php/topic/38295-extension-jii/
- JsFiddle: ..coming soon..
BackBone.js ?
Hi
Excellent extension, I can stop wondering if this extension is linked to a much broader prject as using it with frameworks like Backbone ? or other .
If it is I'd really be interested in particiapting :)
Cheers
Re: BackBone.js ?
Thank you for your comment. :D
I am mainly using knockout js as a Javascript library and this extension have been developed to ease Yii to knockout interactions. I guess this aswers your question.
Anyway, I still haven't planned future developements yet, so I am open to and I will appreciate any contribution.
Nice extension
Thank you for this, but I suggest to think about it as a behavior will be much easier to use and maintain.
Re: Nice extension
Thank you for your comment Cherif.
I never went deep into behaviours, that is why I'd like you could explain with a few more words which way they could make this extensions easier to use and to maintain.
Furthermore I see behaviors as something that can deviate the application flow under particular conditions. But I am not able to identify which conditions you could be thinking about.
Behaviors
The behavior extends CActiveRecordBehavior or CModelBehavior is to place where I suggest to put the code for this extension I want to generate Models for Knockout and convert the Model.attributes to observables and relations (HAS_MANY, MANY_MANY) to obervableArray consider this extension to have an idea ejsonbehavior.
Hope it helps
Interesting
Nice!
I have an external site I need to extract data from and will probably push data to in the future. They have a great API that is REST-FUL and return JSON formatted data. I just don't know how to deal with all the data I get back from the api calls.
RE: Behaviors, Interesting
@Cherif
Thank you. That is clear.
Even if I do not think that behaviors are a suitable approach to this extension (there are a few reasons that it would take to long to explain outside a forum), I think that what you are looking for - and that perhaps will be useful to others and to me too - can be achieved in the following way (of course it actually requires a little more typing:
// this should make available // eager loaded relations: BELONGS_TO, HAS_MANY, MANY_MANY // i.e. : $model = Model::model()->with('name_of_relation')->findAll(); $json_model = Yii::app()->jii->jsonize($model); Yii::app()->jii->addModel('model', $json_model);
On your Javascript code:
~~~
[javascript]
...
// the following feature will be available in jii-0.0.3
var observable_attribute = jii.models.model.attribute_one.getObservable();
...
~~~
Anyway I think Jii could become in a near future a Javascript library for Yii.
I suggest we use Jii forum page for further comments on this issue: in this way we hopefully will benefit from other people's opinions and suggestions. Many thanks :D
@AustinGeek
Well, If you need to encode models to JSON you can use Jii Jsonizer:
If your aim is to decode JSON data into models you can create your own CModel classes defining your custom attributes and validation rules, than you can:
// json from REST API // this returns an array // see http://php.net/manual/en/function.json-decode.php $json_array = json_decode($json_string, true); $your_model = new YourModel(); $your_model->attributes = $json_array;
KO Mapping
You could also include support for ko mapping plugin, its very good for complex models (ie. nested models).
I haven't tested your code yet, as I already use my own encoding with mapping plugin. Basicly I convert model into array and then encode into json and then pass it to ko.mapping.
It supports deeply nested models, arrays of models, just any complex object.
@cgabbanini Forum page
+1 for the forum page (github, roadmap suggestion etc...)
Comments regarding implementations
I have just moved a few comments about further or future implementations or request for support of particular features to Jii forum page, in order to make it easier for us to discuss about any topic.
Nonetheless I would like to thank you for your feedback, which I always appreciate: thank you. :)
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.