1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2006-2011 Strobe Inc. and contributors. 4 // Portions ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 /** 9 @namespace 10 11 The SC.ContentDisplay mixin makes it easy to automatically update your view 12 display whenever relevant properties on a content object change. To use 13 this mixin, include it in your view and then add the names of the 14 properties on the content object you want to trigger a displayDidChange() 15 method on your view. Your updateDisplay() method will then be called at the 16 end of the run loop. 17 18 ## Example 19 20 MyApp.MyViewClass = SC.View.extend(SC.ContentDisplay, { 21 22 contentDisplayProperties: ['title', 'isEnabled', 'hasChildren'], 23 24 ... 25 }); 26 27 @since SproutCore 1.0 28 */ 29 SC.ContentDisplay = { 30 31 /** @private */ 32 concatenatedProperties: 'contentDisplayProperties', 33 34 /** 35 Add an array with the names of any property on the content object that 36 should trigger an update of the display for your view. Changes to the 37 content object will only invoke your display method once per runloop. 38 39 @type Array 40 @default [] 41 */ 42 contentDisplayProperties: [], 43 44 /** @private 45 Setup observers on the content object when initializing the mixin. 46 */ 47 initMixin: function() { 48 this._display_contentDidChange(); 49 }, 50 51 /** 52 * Remove observer on existing content object, if present 53 * @private 54 */ 55 destroyMixin: function () { 56 if (!this._display_content) return; 57 this._display_stopObservingContent(this._display_content); 58 this._display_content = null; 59 }, 60 61 /** @private */ 62 _display_beginObservingContent: function(content) { 63 var f = this._display_contentPropertyDidChange; 64 65 if (SC.isArray(content)) { 66 content.invoke('addObserver', '*', this, f); 67 } 68 else if (content.addObserver) { 69 content.addObserver('*', this, f); 70 } 71 }, 72 73 /** @private */ 74 _display_stopObservingContent: function(content) { 75 var f = this._display_contentPropertyDidChange; 76 77 if (SC.isArray(content)) { 78 content.invoke('removeObserver', '*', this, f); 79 } 80 else if (content.removeObserver) { 81 content.removeObserver('*', this, f); 82 } 83 }, 84 85 /** @private */ 86 _display_contentDidChange: function(target, key, value) { 87 // handle changes to the content... 88 if ((value = this.get('content')) === this._display_content) return; 89 90 // stop listening to old content. 91 var content = this._display_content; 92 if (content) this._display_stopObservingContent(content); 93 94 // start listening for changes on the new content object. 95 content = this._display_content = value; 96 if (content) this._display_beginObservingContent(content); 97 98 this.displayDidChange(); 99 }.observes('content'), 100 101 /** @private Invoked when properties on the content object change. */ 102 _display_contentPropertyDidChange: function(target, key, value, propertyRevision) { 103 if (key === '*') { 104 this.displayDidChange() ; 105 } else { 106 // only update if a displayProperty actually changed...s 107 var ary = this.get('contentDisplayProperties') ; 108 if (ary && ary.indexOf(key)>=0) this.displayDidChange(); 109 } 110 } 111 112 } ; 113