我正在尝试在ember中构建表单元素。表单元素包含用于上传图片的Ember视图/组件,一旦上传图片,则显示图片的缩略图。表单还包含重置和提交按钮。单击“重置”时,文件输入框将清除,因此我知道“onreset”DOM事件正在触发。让我尝试图:
Accordion: {
photoUpload: {
fileUpload: {
input: {}
},
resetButton,
saveButton
}
}
Accordion: simply houses components and handles its own open/close actions.
photoUpload: has both a template and a view/controller.
photoUpload.hbs: has a form element that houses the fileUpload component and the two buttons.
photoUpload.js: handles the actions from the template, such as making the call to the web services.
fileUpload: Handles the uploading of files, determining there type and displaying a preview/thumbnail if the file is an image.
input: handles file browsing
所以我试图解决的真正问题是如何从resetButton中启动一个可以在姐妹元素fileUpload中听到/执行的动作/功能/事件。当我点击执行我的重置按钮时,我清除输入元素我认为我需要一些如何从我的fileUpload组件中观察此输入组件中的属性,然后清除图像预览。
以下是photoUpload模板的示例:
<p>Upload a photo.</p>
<form {{action 'savePhoto' on='submit'}}>
{{view FileUpload showPreview=true showProgress=true valueBinding="photo" fileBinding="view.file"}}
<div class="controls">
{{#view Button type="secondary" function="reset" action="resetPhoto"}}Cancel{{/view}}
<input class="primary" type="submit" value="Save">
</div>
</form>
以下是输入组件的示例:
function() {
var _InputElement = Ember.View.extend({
tagName: 'input',
attributeBindings: ['type', 'name', 'value', 'readonly', 'disabled', 'required'],
typeBinding: 'parentView.type',
idBinding: 'parentView.GUID',
valueBinding: 'parentView.value',
readonlyBinding: 'parentView.readonly',
disabledBinding: 'parentView.disabled',
requiredBinding: 'parentView.required',
nameBinding: 'parentView.name',
change: Ember.aliasMethod( '_updateValue' ),
keyUp: Ember.aliasMethod( '_updateValue' ),
_updateValue: function() {
var old = this.get( 'value' );
var current = this.$().val();
if( current != old ) { // -- value actually changed
this.set( 'value', this.$().val());
}
}
});
return Ember.View.extend({
classNames: ['input'],
classNameBindings: ['error:error', '_typeClass'],
attributeBindings: ['data-label', 'data-name', 'readonly', 'disabled', 'required'],
_InputElement: _InputElement,
type: 'text', // text, password, radio, checkbox, select, etc
error: null,
label: null,
prefix: null,
postfix: null,
name: null,
value: null,
readonly: false,
disabled: false,
showInputBeforeLabel: false,
'data-name': function() {
var name = this.get( 'name' );
return (!Ember.isEmpty( name ) ? name.camelize() : undefined);
}.property( 'name' ),
'data-label': function() {
var label = this.get( 'label' );
return (!Ember.isEmpty( label ) ? label.camelize() : undefined);
}.property( 'label' ),
_typeClass: function() {
return 'input-%@'.fmt( this.get( 'type' ));
}.property( 'type' ),
_InputElementGUID: function() {
var childViews = this.get('childViews');
if ( childViews && childViews[0] ) { // -- only works if there is ONE child view, as in, ONE _InputElement
return childViews[0].get('elementId');
}
}.property( '_InputElement', 'childViews.[]' ),
_yieldTemplate: '{{yield}}',
_labelTemplate: '<label {{bind-attr for="view._InputElementGUID"}}>{{view.label}}</label>',
_preLabelTemplate: function() { return '{{#if view.label}}{{#unless view.showInputBeforeLabel}}' + this.get( '_labelTemplate' ) + '{{/unless}}{{/if}}'; }.property(),
_postLabelTemplate: function() { return '{{#if view.label}}{{#if view.showInputBeforeLabel}}' + this.get( '_labelTemplate' ) + '{{/if}}{{/if}}'; }.property(),
_errorTemplate: '{{#if view.error}}<label class="error form-error" {{bind-attr for="view._InputElementGUID"}}>{{view.error}}</label>{{/if}}',
_prefixTemplate: '{{#if view.prefix }}<div class="prefix input-prefix" >{{view.prefix }}</div>{{/if}}',
_postfixTemplate: '{{#if view.postfix}}<div class="postfix input-postfix">{{view.postfix}}</div>{{/if}}',
layout: function() {
return Ember.Handlebars.compile( ''
+ this.get('_preLabelTemplate') + '\n'
+ this.get('_prefixTemplate') + '\n'
+ this.get('_yieldTemplate') + '\n'
+ this.get('_postfixTemplate') + '\n'
+ this.get('_postLabelTemplate') + '\n'
+ this.get('_errorTemplate')
)
}.property(),
template: Ember.Handlebars.compile( '{{view view._InputElement}}' )
});
});
并且输入组件的使用方式如下:
'<div class="input-file-button-wrapper">{{view view._InputElement}}</div>\
<div class="input-file-preview-wrapper">\
<img {{bindAttr src="view.file"}} {{bindAttr title="view.fileName"}}/>\
</div>'
提前致谢!
答案 0 :(得分:1)
您可以在视图中使用此功能:<button {{action reset}}>Reset</button>
并让该操作处理您想要执行的操作。
答案 1 :(得分:0)
我最终需要使用简单的绑定。我误解了绑定在Ember中是如何工作的,并且认为绑定变量/属性只能在与该视图/组件实例化相关联的操作中使用。实际上,您可以使用实例化其他组件的组件内部的任何绑定变量。我的解决方案是绑定我在fileUpload组件中找到的变量“haveUploadedFile”。然后在使用我的重置按钮启动的操作中,我将该变量设置为false。
希望这可以帮助有人在路上。
fileUpload.hbs现在看起来像这样:
<p>Upload a headshot.</p>
<form {{action 'savePhoto' on='submit'}}>
{{view Vember.FileUpload showPreview=true showProgress=true valueBinding="photo" fileBinding="view.file" haveUploadedFileBinding="view.haveUploadedFile"}}
<div class="controls">
{{#view Vember.Button type="secondary" function="reset" action="resetPhoto"}}Cancel{{/view}}
<input class="primary" type="submit" value="Save">
</div>
</form>