
å€ãã®å ŽåãKnockout.jsã¯ASP.NET MVCãšçµã¿åãããŠäœ¿çšââãããŸããçµå±ã®ãšãããã©ã€ãã©ãªã¯ã¯ã©ã€ã¢ã³ãããžãã¯ã®èšè¿°ãå€§å¹ ã«ç°¡çŽ åããŸãã ãã ããã¯ã©ã€ã¢ã³ã/ãµãŒããŒéçºã§ã¯å€ãã®å žåçãªåé¡ãçºçããŸããã¡ã€ã³ã¢ãã«ãšãã®åŠçã®ããžãã¯ã®äžéšã¯ãã¯ã©ã€ã¢ã³ãïŒJavaScriptïŒãšãµãŒããŒïŒCïŒ/ VBïŒã®äž¡æ¹ã§èšè¿°ããå¿ èŠããããŸãã ããã«ããµãŒããŒã¡ãœããã«å¯Ÿããã¯ã©ã€ã¢ã³ãã®ã¢ããŒã«ã«é¢é£ããã«ãŒãã³éšåããããåŠçã®ããã®ã¢ãã«ãæž¡ããŸãã ããããæ²ããããšã¯ãããŸããïŒ ããã§Knockout MVCãã§ããŸãããããã¯Knockout.jsã®.NETã·ã§ã«ã§ãå¿ èŠãªãã¹ãŠã®JavaScriptã³ãŒããçæããŸãã ã¢ãã«ãCïŒã§èšè¿°ããMVVMã¹ã¿ã€ã«ã§ãåHTMLèŠçŽ ã«å¯ŸããŠãã¢ãã«ã®ã©ã®ããããã£ã«ãã€ã³ãããå¿ èŠãããããæå®ããå¿ èŠããããŸãïŒåŒå šäœãæå®ããããšãã§ããŸã-ãããã¯jsã«å€æãããŸãïŒã ãããã£ãŠã1è¡ã®JavaScriptãªãã§å®å šãªã¯ãã¹ãã©ãŠã¶ã¯ã©ã€ã¢ã³ãWebã¢ããªã±ãŒã·ã§ã³ãååŸã§ããŸãã
ãããŠããå°ã
ã¢ãã«
ã¢ãã«ã¯ããµãŒããŒäžã§äžåºŠäœæãããŸãïŒããšãã°ãCïŒã§ïŒã ã¯ã©ã€ã¢ã³ãåŽã§ã¯ããã¹ãŠã®JavaScriptã³ãŒããèªåçã«çæãããŸãã ããã«ãéåžžã®ããããã£ã ãã§ãªããJavaScriptã«å€æãããéåžžã«è€éãªåŒãèšè¿°ã§ããŸãã ããã«ãããã¯ã¡ã€ã³ã¢ãã«ã ãã§ãªãããã®ãµãã¢ãã«ã«å¯ŸããŠãè¡ãããŸãïŒçŽç²ãªKnockout.jsã§ã¯ãããã¯ããã»ã©ç°¡åã§ã¯ãããŸããïŒã ããšãã°ããã®ãããªã¢ãã«ã«ã€ããŠèª¬æããŸãã
public class Item { public string FirstName { get; set; } public string LastName { get; set; } public Expression<Func<string>> FullName() { return () => FirstName + " " + LastName; } } public class Model { public List<Items> Items { get; set; } } // ... var model = new Model { Items = new List<Item> { new Item {FirstName = "Annabelle", LastName = "Arnie"}, new Item {FirstName = "Bertie", LastName = "Brianna"}, new Item {FirstName = "Charles", LastName = "Cayenne"}, } };
ãŸãã次ã®JavaScriptãèªåçã«çæãããŸãã
var viewModelJs = {"Items":[{"FirstName":"Annabelle","LastName":"Arnie"},{"FirstName":"Bertie","LastName":"Brianna"},{"FirstName":"Charles","LastName":"Cayenne"}]}; var viewModelMappingData = { 'Items': { create: function(options) { var data = ko.mapping.fromJS(options.data); data.FullName = ko.computed(function() { try { return this.FirstName()+' '+this.LastName()} catch(e) { return null; } ;}, data); return data; }}}; var viewModel = ko.mapping.fromJS(viewModelJs, viewModelMappingData); ko.applyBindings(viewModel);
ãã®äŸã§ã¯ãçµæã®JavaScriptã¯æ¯èŒçåçŽã§ããããããã«è€éãªã¢ãã«ã§ã¯ããã³ã§æžãã®ã¯ããã»ã©ããŸããããŸããã ãªãã¡ã¯ã¿ãªã³ã°ããå Žåã¯ãJavaScriptã¢ãã«ãšCïŒã¢ãã«ãåæããŠéåžžã«æ éã«å€æŽããå¿ èŠããããŸãïŒéåžžã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã®ã¢ãã«ã®ã¢ã¯ã·ã§ã³ã®ããžãã¯ãèšè¿°ããããã«CïŒã¢ãã«ãå¿ èŠã§ãïŒã
ããŒã¿ãã€ã³ãã£ã³ã°
ASP.NET MVCã䜿çšããŠããå ŽåãããããRazor View Engineã䜿çšããŠãã¥ãŒãèšè¿°ããŸãã ããã§ãªãå Žåã¯ãå°ãªããšããã®ãšã³ãžã³ã®æ©èœã«ç²Ÿéããããšããå§ãããŸã-ãµã€ãã®ã¬ã€ã¢ãŠããæ°ããã¬ãã«ã«åŒãäžããŸãã 以äžã¯ãRazorå°çšã®è¡šçŸã®äŸã§ãã
ããšãã°ãã¢ãã«ã®ããããã£Aã®å€ãå«ãTextBoxãäœæããŸãã æžãã ãã§ååã§ãïŒ
@ko.Html.TextBox(m => mA)
æ¬åŒ§å ã¯ãã¢ãã«mããããŒã¿ããã€ã³ãããããããã£ãšäžèŽãããã©ã ãåŒã§ãã ãã®å ŽåãCïŒã§åŒãèšè¿°ããŠããŸããããã¯ãIntelliSenseã次ã®ããšãæ¯æŽããããšãæå³ããŸãã

ãããŠã誀ã£ãŠååãééã£ãŠã€ã¥ã£ãå Žåãç·šé段éã§ãããã«ã€ããŠç¥ãã§ããããã¹ã¿ãžãªã®èµ€ãã¹ããªããã¯ãã©ãããééã£ãŠããããšã瀺ããŸãã
ããã§ã¯ããã£ãšè€éãªäŸãèŠãŠã¿ãŸãããã ããšãã°ãã¢ãã«ã§2ã€ã®æ¡ä»¶ãåæã«æºããããŠããå Žåã«ã®ã¿ãããŒãžã®äžéšã衚瀺ããå¿ èŠããããŸãã ç§ãæžãå¿ èŠããããã¹ãŠïŒ
@using (ko.If(model => model.Condition1 && model.Condition2))
次ã«ãäžæ¬åŒ§ã§ããã¬ãŒã³ããŒã·ã§ã³ã®å¯Ÿå¿ããéšåã瀺ãããŸãã ã·ã³ãã«ã§ããïŒ çµå±ããã®ãããªè¡ã1ã€æžããã ãã§ãããã«ãããå¿ããããšãã§ããŸããCondition1ãšCondition2ã®ç¶æ ãç£èŠããå¿ èŠã¯ãããŸãããèŠçŽ ã®å¯èŠæ§ãå¶åŸ¡ããjs-codeãæžããªã©ã§ãã ãããŠãæ¡ä»¶ã®1ã€ãååå€æŽãŸãã¯èšç®ããããã£ã«å€æŽãããšããªãã¡ã¯ã¿ãªã³ã°ããžãã¯ãåŒãä¿®æ£ããŸãïŒããã«å¿ããŠãçæãããJavaScriptãä¿®æ£ãããŸãïŒã
Knockout MVCã«ã¯ãå€ãã®äŸ¿å©ãªæ§é ãå«ãŸããŠããŸãã ããšãã°ãã³ã¬ã¯ã·ã§ã³ã®èŠçŽ ãå埩åŠçããåèŠçŽ ã«ãšã£ãŠéèŠãªãã®ãå°ãåºãã®ã¯éåžžã«ç°¡åã§ãã
@using (var items = ko.Forearch(m => m.Items))
ãã¹ãŠã®å©çšå¯èœãªæ§ææ§é ã®å®å šãªèª¬æã¯ããã¥ã¡ã³ãã§èŠã€ããããšãã§ããŸãã
ãµãŒããŒã¢ã¯ã»ã¹
ããã§ã¯ãã¢ãã«ã§æäœãå®è¡ãããµãŒããŒåŽã®ã¡ãœãããåŒã³åºããã¿ã³ãäœæããŠã¿ãŸãããã JavaScriptã³ãŒãã§æ¬¡ã®ç¹ãèæ ®ããå¿ èŠããããŸãã
- çŸåšã®ã¢ãã«ã«é¢ããããŒã¿ãåéããããããè¡ã«ã·ãªã¢ã«åããå¿ èŠããããŸã
- ãã®è¡ããµãŒããŒã«ajaxéä¿¡ãããã¿ã³ã«ãã€ã³ãããå¿ èŠããããŸã
- ãµãŒããŒããããŒã¿ãåä¿¡ããèŠèŠèŠçŽ ãæŽæ°ããããžãã¯ãäœããã®åœ¢ã§èšè¿°ããå¿ èŠããããŸã
ãããŠïŒ ãããè¡ãå¿ èŠã¯ãããŸããïŒ æ¬¡ã®è¡ãæžãã ãã§ãïŒ
@ko.Html.Button("Some text", "FooAction", "Foo")
ææ ®æ·±ãèªè ã¯ããµãŒããŒã¡ãœããã«ããã€ãã®ãã©ã¡ãŒã¿ãŒãæž¡ãããå Žåã¯ããšå°ããŸãã
@ko.Html.Button("Some text", "FooAction", "Foo", new { index = 0, caption = "Knockout MVC"})
ãããŠããµãŒããŒäžã®å¯Ÿå¿ããã¡ãœããã説æããŸãã
public class FooController : KnockoutController { public ActionResult FooAction(FooModel model, int index, string caption) { model.FooAction(index, caption); // return Json(model); } }
以äžã§ãïŒ 1è¡è¿œå ããå¿ èŠã¯ãããŸããïŒ æè¡ã«ãŒãã³ã䌎ãã¯ã©ã€ã¢ã³ã/ãµãŒããŒã¢ããªã±ãŒã·ã§ã³ããããšããäºå®ãå¿ããããšãã§ããŸããéçºäžã¯ãã¢ãã«ããžãã¯ã®ã¿ã«éäžããå¿ èŠããããŸãã ããã§ããããã¹ãŠãã©ã®ããã«æ©èœãããã詳ããèŠãããšãã§ããŸã
ã³ã³ããã¹ããæäœãã
Knockout.jsã§çŽæ¥è¡ãããããšã¯ãŸã£ãã䟿å©ã§ã¯ãããŸãããããã¯ã³ã³ããã¹ãã§æ©èœããŸãã ãã¹ãããã
foreach
ã䜿çšã
with
æ§æäœã䜿çšãããšããã¹ããããã³ã³ããã¹ããçºçããŸãã ãã¹ãã®ã¬ãã«ã1ã€ã®å Žåããã¹ãŠãæ£åžžã§ãã ãã ãã4ã5ã¬ãã«ã®ãã¹ããçºçããè€éãªã¢ããªã±ãŒã·ã§ã³ãäœæããŠããå Žåã
$parentContext.$parentContext.$parentContext.$index
$parents[2].name
ãŸãã¯
$parentContext.$parentContext.$parentContext.$index
ãšãã圢åŒã®æ§é ã«ééããããšããããŸãã ãã®ãããªã³ãŒããèªèããããšã¯éåžžã«é£ããããªãã¡ã¯ã¿ãªã³ã°ã«é¢ããŠã¯å®å šã«æ²ãããªããŸãã Knockout MVCã§ã®èšè¿°ã¯éåžžã«ç°¡åã§ã-ãã¹ãŠã®ã³ã³ããã¹ãã«ç¬èªã®ååãä»ããããŸããïŒ ãããŠãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
@using (var subModel = ko.With(m => m.SubModel)) { using (var subSubModel = subModel.With(m => m.SubSubModel)) { @subSubModel.Html.Span(m => ko.Model.A + " " + subModel.GetIndex() + " " + mB) } }
ãã¹ããããåŒèªäœã¯æ¬¡ã®ããã«ãªããŸãã
<span data-bind="text : $parents[1].A()+' '+$parentContext.$index()+' '+B()"></span>
äŸãèŠãããšãã§ããŸãã
ãã®ä»ã®ãããããã³
ãšããããã©ã€ãã©ãªã«ã¯ãç掻ãããç°¡åã«ããããšãã§ããããã€ãã®è¿œå æ©èœããããŸãã
- é
延èªã¿èŸŒã¿ããŒã¿ã ããŒãžãé·æéèªã¿èŸŒãŸãããšãåžžã«è¿·æã«ãªããŸãã äžæºãæã€ãŠãŒã¶ãŒã¯ãããŠã³ããŒãã®å®äºãåŸ
ããã«ãµã€ããé¢ããããšããããŸãã ããŒãžãéåžžã«å°ãããã»ãšãã©ã®å ŽåJavaScriptãããŒããããå Žåãç¹ã«ãã£ããããŸãã Knockout MVCã®å¯èœæ§ã®1ã€ã¯ã
Lazy
ãšããå°ããªåèªã1ãæã«æžãããšãã§ããããšã§ã-ãããŠãèŠã-ããŒãžã®èªã¿èŸŒã¿åŸã«è¿œå ã®ajaxãªã¯ãšã¹ãã§ããŒã¿ãèªã¿èŸŒãŸããŸãã é©åãªJavaScriptã³ãŒããæåã§èšè¿°ããããšã¯ããã»ã©é£ããããšã§ã¯ãªãããšã¯æããã§ããããã®ãããªãœãªã¥ãŒã·ã§ã³ãããã«äœ¿çšã§ããããã«ãªã£ãå Žåã§ããããã¯çŽ æŽãããããšã§ãã ããªãã¯ãããçããŠããäŸã§ã©ã®ããã«èŠããããèŠãããšãã§ããŸãã - ã«ã¹ã¿ã JavaScriptã®è¿œå ã ãããŠãå¥ã®æ²ããç¶æ³ããããŸãã次ã®ãã¬ãŒã ã¯ãŒã¯ã䜿ãå§ããã®ã§ããã¹ãŠã奜ãã§ããã1ã€ã®å°ããªæ©èœã§ã¯äžååã§ãã ãããŠããã¬ãŒã ã¯ãŒã¯ã䜿çšããªããã°ããã®æ©èœãç°¡åã«è¿œå ã§ããŸããããã®äœ¿çšã®ã³ã³ããã¹ãã§ã¯ãå®è¡ããããšã¯äžå¯èœã§ããããéåžžã«å°é£ã§ãã Knockout MVCã䜿çšãããšãæ¢ã«äœæãããŠããèªåçæã¢ãã«ã«ããŒã¿ãã€ã³ãã£ã³ã°ãè¿œå æ©èœãæåã§è¿œå ã§ããããããã®ãããªç¶æ³ãæããå¿ èŠã¯ãããŸãã-ããªãã®èªç±ã¯ç¡éã§ãïŒ ãããŠåã³çããŠããäŸããããŸã
- ä»ã®ã©ã€ãã©ãªãšã®äºææ§ ã Knockout.jsã䜿çšããå Žåãããã©ã«ãã§ã¯ããã§ã«ä»ã®JavaScriptã©ã€ãã©ãªïŒjQueryãPrototypeãªã©ïŒãŸãã¯ãã®ãã©ã°ã€ã³ãšã®äºææ§ããããŸãã ããŠãããšãã°ã jQuery.Validation ã§ã®äœæ¥ãèŠãããšãã§ããŸã
ãŸãšã
èŠçŽãããšã Knockout MVCã®äž»ãªæ©èœïŒ
- 人æ°ã®ããjockã©ã€ãã©ãªKnockout.jsã«åºã¥ããŠäœæ
- ASP.NET MVC3ãšã®å®å šãªçµ±å
- Model-View-View ModelïŒMVVMïŒãã¿ãŒã³ã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®äœæ
- ïŒç¹å®ã®ããããã£ããã³åŒãžã®ïŒãã¹ãŠã®ããŒã¿ãã€ã³ãã£ã³ã°ã¯ãCïŒ/ VBã§èšè¿°ãããŸãã
- ã¢ãã«ã¯ãµãŒããŒäžã§äžåºŠã ãèšè¿°ããå¿ èŠããããŸã
- IntelliSenseã¯ãã¹ãŠã®ããŒã¿ãã€ã³ãã£ã³ã°ãæžã蟌ãããã«åäœããŸã
- JavaScriptã³ãŒããèšè¿°ããå¿ èŠã¯ãŸã£ãããããŸãã
- ãããŠãæ¥ç¶ãããjsã³ãŒãã®ãµã€ãºã¯éåžžã«å°ããã§ãïŒå§çž®ãããKnockoutã¯çŽ40KbããããŸãïŒ
- Ajaxã®ç©æ¥µçãªäœ¿çš-ãã¹ãŠã®ãµãŒããŒã¡ãœããã¯ããŒãžããªããŒãããããšãªãæ©èœããŸã
- æžããããèªã¿ãããçãç°¡æœãªæ§æ
- éçºã¯éåžžã«ç°¡åã§ãéåžžã®ã¢ããªã±ãŒã·ã§ã³ã®äœæã«äŒŒãŠããŸã-ã¯ã©ã€ã¢ã³ããšãµãŒããŒã®çžäºäœçšãå®å šã«å¿ããããšãã§ããŸã
- äŸåé¢ä¿ã¯ã»ãšãã©ãããŸãããKnockout.jsïŒããèªäœïŒãšjQueryïŒãããŠããããããªãã«æ¢ã«æ¥ç¶ãããŠããïŒã ãã§ãã
- ãã©ãŠã¶ãŒéã®äºææ§ïŒIE 6 +ãFirefox 2 +ãOpera 10 +ãChromeãSafari
- ä»ã®ã©ã€ãã©ãªïŒjQueryãPrototypeãããã³å¿ èŠãªãã¹ãŠïŒãšã®å®å šãªäºææ§
- 詳现ãªããã¥ã¡ã³ããAPIã®è©³çŽ°ãªèª¬æãå€ãã®å®äŸ