{"comment":{"created_at":"2011-10-21T11:19:43Z","body":"The rules are very simple:\r\n\r\nIf the value is an observable:\r\n1- if it responds to formatted(), the return of formatted() is used;\r\n2- otherwise, it's value is used through Object.toString()\r\n\r\nIf it is not an observable, the expression is evaluated and processed by Object.toString()\r\n\r\nOn your particular example, only the first one would be formatted. But you got a point there. For it to work properly, it should have been written like:\r\n\r\n    data-bind=\"text: isEnabled, css: { myClass: isEnabled() }\"\r\n\r\nAnd I recognize this will break current code if this behavior is changed... Not sure how to deal with that... Maybe this should be enabled by context only, and they could be configurable:\r\n\r\n    ko.formattableBindings = ['text', 'attr']\r\n\r\nThis way, a \"title\" attribute as well as the tag content could be formatted while css classes would not.\r\n\r\nLet me put this in another way.\r\n\r\nMost OO languages will have a toString (to_s, etc) that will convert an object to a user readable format. This convention allows objects to be translated to human readable format implicitly in several cases and each class is able to define this conversion.\r\n\r\nIn the case of knockout, there are clearly two separate concerns: the view and the model. Clearly, that human readable format only makes sense in the view in a proper written application using the MVVM pattern. So, instead of being explicit I would rather prefer to keep my views clean while the convention will allow my formatted versions to be displayed instead of the raw values. This would also be consistent among all Knockoutjs applications and even plugins could take advantage of this convention.\r\n\r\nIf I can't change your mind, it is ok. My current solution is not that bad: (in CoffeeScript)\r\n\r\n    class MyClass\r\n      # ...\r\n      registerKnockoutExtenders: ->\r\n        ko.extenders.boolean = (target) =>\r\n          target.formatted = @booleanFormatter\r\n          target\r\n      booleanFormatter: -> if this() then 'Yes' else 'No'\r\n      # ...\r\n      viewModel:\r\n        myBoolean: ko.observable(@myBoolean).extend(boolean: true)\r\n\r\nIn my view, I have data-bind=\"text: myBoolean.formatted()\".\r\n\r\nI just would prefer to be able to just say data-bind=\"text: myBoolean\" instead...","updated_at":"2011-10-21T11:19:43Z","url":"https://api.github.com/repos/SteveSanderson/knockout/issues/comments/2480086","id":2480086,"user":{"gravatar_id":"7c110e6606bd4751a3261998ac6e6ee7","avatar_url":"https://secure.gravatar.com/avatar/7c110e6606bd4751a3261998ac6e6ee7?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","url":"https://api.github.com/users/rosenfeld","id":32246,"login":"rosenfeld"}},"action":"created","issue":{"number":180,"created_at":"2011-10-20T18:16:13Z","pull_request":{"diff_url":null,"patch_url":null,"html_url":null},"body":"Suppose a boolean observable:\r\n\r\n    viewModel.myBoolean = ko.observable(false)\r\n\r\nI want myBoolean() to return false, but want data-bind=\"text: myBoolean\" to use \"No\" instead.\r\n\r\nNot sure what would be the best way to design this API, but here are some alternatives:\r\n\r\n    ko.observable(false).extend(myBooleanFormatter)\r\n\r\nmyBooleanFormattter could introduce a new \"formatted\" function to do the job. The convention in the views would be to call any formatted() method on the observable if the method exists, instead of calling toString() in the value of the observable.\r\n\r\nFor simplifying this, an option could be:\r\n\r\n    ko.observable(false).formatter(myBooleanFormatter)\r\n\r\nwhere myBooleanFormatter would get the raw value and return a string representation.\r\n\r\nThis would allow me to have clean views using data-bind=\"text: myBoolean\" instead of data-bind=\"text: myBoolean().formatted()\".\r\n\r\nDoes it make sense?","comments":14,"title":"Add support for formatted observables","updated_at":"2011-10-21T11:19:43Z","url":"https://api.github.com/repos/SteveSanderson/knockout/issues/180","id":2007642,"assignee":null,"milestone":null,"closed_at":null,"user":{"gravatar_id":"7c110e6606bd4751a3261998ac6e6ee7","avatar_url":"https://secure.gravatar.com/avatar/7c110e6606bd4751a3261998ac6e6ee7?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","url":"https://api.github.com/users/rosenfeld","id":32246,"login":"rosenfeld"},"html_url":"https://github.com/SteveSanderson/knockout/issues/180","labels":[],"state":"open"},"legacy":{"issue_id":2007642,"comment_id":2480086}}