Closed etodanik closed 10 years ago
It's magic.
:D Yes I can see that it could be a bit confusing. Basically it's hard to dynamically bind a value against a ng-model
, and I didn't want to end up doubling the number of watches by using an intermediary value on scope or a isolated scope with double binding. What I ended up doing was just before inserting the template I do a string replacement of $$value$$
and place whatever is the key, so we end up with a nice looking ng-model.
You can see the code here. https://github.com/Textalk/angular-schema-form/blob/development/src/services/decorators.js#L56
Alright, so - I kinda get what happens, and I see that you basically replace it with a reference to the model
variable on $scope
. I wonder, however, how did something I've done work.
I basically needed a file upload interaction, so instead of making my own directive that contained the upload functionality, I set ng-controller
on the parent div, kind of like this:
<div class="form-group" ng-controller="FileCtrl" ng-class="{'has-error': hasError()}">
<label class="control-label" ng-show="showTitle()">{{form.title}}</label>
<input ng-show="form.key"
style="background-color: white"
type="file"
class="form-control"
ng-file-select="onFileSelect($files)" />
<span class="help-block">{{ (hasError() && errorMessage(schemaError())) || form.description}}</span>
</div>
Then, inside the JS file I did something like:
angular.module('schemaForm').config(
['schemaFormProvider', 'schemaFormDecoratorsProvider', 'sfPathProvider',
function(schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) {
var file = function(name, schema, options) {
if (schema.type === 'string' && (schema.format === 'file')) {
var f = schemaFormProvider.stdFormObj(name, schema, options);
f.key = options.path;
f.type = 'file';
options.lookup[sfPathProvider.stringify(options.path)] = f;
return f;
}
};
schemaFormProvider.defaults.string.unshift(file);
//Add to the bootstrap directive
schemaFormDecoratorsProvider.addMapping(
'bootstrapDecorator',
'file',
'directives/decorators/bootstrap/file/file.html'
);
schemaFormDecoratorsProvider.createDirective(
'file',
'directives/decorators/bootstrap/file/file.html'
);
}
]);
angular.module('schemaForm').controller(
'FileCtrl',
['$scope', '$upload',
function($scope, $upload) {
$scope.onFileSelect = function($files) {
for (var i = 0; i < $files.length; i++) {
var file = $files[i];
$scope.upload = $upload.upload({
url: '/upload',
method: 'POST',
file: file,
}).progress(function(evt) {
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
}).success(function(data, status, headers, config) {
// file is uploaded successfully
$scope.model[$scope.form.key[0]] = data;
});
}
}
}
]);
Now - my question is why the )$()$ does it work? :) Also, why do I "magically" have the model
on my $scope
? Line 46 shouldn't work, but it does. How did form
and model
magically make it onto my freshly created controller scope?
Scope inheritance to the rescue!
The form is exported on scope by the decorator directive (created by the factory service in decorators.js ) https://github.com/Textalk/angular-schema-form/blob/master/src/services/decorators.js#L47
The model object is exported on scope by sf-schema directive so that ng-model
has something to bind to. This means $scope.model[$scope.form.key[0]] = data;
works for you since you have a flat structure, but add some arrays or objects and it will fail. The safest bet is to do a directive that requires the ng model controller. That way you can also invalidate the form if something goes wrong with the upload.
So you mean , construct a directive that effectively wraps the file upload directive into something of my own, and not complicate the actual decorator?
Yes exactly. If you do a directive that plays nicely with ng-model
it should just work. And on the plus side you get a file upload directive you can reuse elsewhere.
Since the
$$value$$
isn't on the controller scope, what the heck is it?I'm trying to adjust this
$$value$$
from a controller scope I created to wrap a file upload field I'm making , and being able to put stuff in$$value$$
is my missing link.