gui: Fix scopes in notification directive (fixes #4941) (#4948)

The directive lives in its own isolated scope (where we put the visible() function). The stuff transcluded into the notification directive lives in the root scope and doesn't have access to the directive scope. Hence we cannot call dismiss() from inside the directive.

Similarly, config does not exist by itself in the directive scope, we need $parent to access the root scope.

Reference: https://docs.angularjs.org/guide/directive#isolating-the-scope-of-a-directive

How this worked before is a mystery. My guess is Angular bug with directive scope that was fixed in 1.3. One possibility is that transclude plus scope: true (which doesn't make sense as that is supposed to be an object) resulted in the root scope being used in the directive itself. This would then "work" as long as there is only one notification, as visible() and dismiss() would then be registered on the root scope, thus accessible from within the notification but also overridden by any notification rendered.
This commit is contained in:
Jakob Borg 2018-05-13 07:44:19 +02:00 committed by GitHub
parent 7d07b19734
commit ed4807d9a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 15 deletions

View File

@ -2,20 +2,13 @@ angular.module('syncthing.core')
.directive('notification', function () {
return {
restrict: 'E',
scope: true,
scope: {},
transclude: true,
template: '<div class="row" ng-if="visible()"><div class="col-md-12" ng-transclude></div></div>',
link: function (scope, elm, attrs) {
scope.visible = function () {
return scope.config.options.unackedNotificationIDs.indexOf(attrs.id) > -1;
}
scope.dismiss = function () {
var idx = scope.config.options.unackedNotificationIDs.indexOf(attrs.id);
if (idx > -1) {
scope.config.options.unackedNotificationIDs.splice(idx, 1);
scope.saveConfig();
}
}
return scope.$parent.config.options.unackedNotificationIDs.indexOf(attrs.id) > -1;
};
}
};
});

View File

@ -6,7 +6,7 @@
<p translate>This is an example notification. ID of the notification should be appended to Options.UnackedNotificationIDs of the config.</p>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="dismiss()">
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="dismissNotification('exampleNotification')">
<span class="fa fa-check"></span>&nbsp;<span translate>OK</span>
</button>
<div class="clearfix"></div>
@ -31,10 +31,10 @@
<p><a href="https://docs.syncthing.net/users/releases.html"><span class="fa fa-fw fa-book"></span>&nbsp;<span translate>Learn more</span></a></p>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="editSettings()">
<button type="button" class="btn btn-sm btn-default pull-right" ng-click="editSettings(); dismissNotification('channelNotification')">
<span class="fa fa-cog"></span>&nbsp;<span translate>Settings</span>
</button>
<button type="button" class="btn btn-sm btn-default" ng-click="dismiss()">
<button type="button" class="btn btn-sm btn-default" ng-click="dismissNotification('channelNotification')">
<span class="fa fa-check"></span>&nbsp;<span translate>OK</span>
</button>
<div class="clearfix"></div>
@ -58,10 +58,10 @@
</div>
<div class="panel-footer clearfix">
<div class="pull-right">
<button type="button" class="btn btn-primary btn-sm" ng-click="activateAllFsWatchers(); dismiss()">
<button type="button" class="btn btn-primary btn-sm" ng-click="activateAllFsWatchers(); dismissNotification('fsWatcherNotification')">
<span class="fa fa-check"></span>&nbsp;<span translate>Yes</span>
</button>
<button type="button" class="btn btn-default btn-sm" ng-click="dismiss()">
<button type="button" class="btn btn-default btn-sm" ng-click="dismissNotification('fsWatcherNotification')">
<span class="fa fa-times"></span>&nbsp;<span translate>No</span>
</button>
</div>

View File

@ -2247,4 +2247,12 @@ angular.module('syncthing.core')
$scope.sizeOf = function (dict) {
return Object.keys(dict).length;
};
$scope.dismissNotification = function (id) {
var idx = $scope.config.options.unackedNotificationIDs.indexOf(id);
if (idx > -1) {
$scope.config.options.unackedNotificationIDs.splice(idx, 1);
$scope.saveConfig();
}
};
});