Open romanesko opened 10 years ago
I had this usecase just today actually.
By removing the following line: https://github.com/Pasvaz/bindonce/blob/master/bindonce.js#L170
And adding scope.bindonceController = bindonceController;
to the following line:
https://github.com/Pasvaz/bindonce/blob/master/bindonce.js#L188
I can call $scope.bindonceController.runBinders();
whenever I want to manually update the DOM. It would be really helpful if the code could be changed to support this.
I'm sorry to let you wait, I have to push some updates, one of them includes the possibility to refresh the binders by user request, I think that would close this issue. I just need a bit of time (very rare thing right now for me) to clean it and push it.
As a follow up to this; I'm guessing you're redoing a lot of the binders themselves here as well?
This like the bo-class binding, or the bo-if need modifying to add or remove elements in either case, not just do the positive effect or nothing? (I'm modifying it myself at the moment for this purpose exactly).
Probably should; I'm just doing it at work atm and not sure how they'd feel about me doing that. But I'll change it on my own and try submit a PR.
I also have this use case and suggested #50 . The API could be bo-rebind="whateverEventName"
. bo-rebind
would listen $on $rootScope for whateverEventName
and call bindonceController.runBinders()
from @dominicglenn 's suggestion.
What do you all think? I'm going to work on this for my own project this week - would others like this api?
cc @Pasvaz
Soon (I think this weekend) I'll publish two new directives, one is onewatcher
and the other is bo-refresh-on
, bo-refresh-on
works exactly as you thought, it uses $on
to listen on the channel declared in the attribute boRefreshOn
and it runs the binders again.
There is another way to achieve this result, in my experimental version I use also a setter to attach a refresh function to the scope, something like bo-refresh-with="refreshMe"
so when you call $scope.refreshMe() bindonce runs the binders. If I can test it enough I could publish also bo-refresh-with
, let's see.
Perfect, that's exactly what I had in mind. Thanks! Let me know if you can use help either implementing or testing.
thank you @rileylark, I appreciate it.
I've got some huge $watches dragging me down and will need to start work on this soon. I'll be happy to offer a PR but don't want to redo work you've already done. @Pasvaz, do you have a branch in progress I can extend?
Hey,
I love the idea of using events, and the idea of one watcher will make a huge appeal to many people.
Is this planned for any time soon?
Thanks a lot.
I'll try to push my branch today, I'm sorry I can't do it as soon as I thought but I'm facing some deadlines.
Hey, no worries, bindonce will save me a ton of time even without this feature. I'd appreciate seeing your branch for this issue even incomplete - I'm sure I'll at least learn about your architecture by seeing where you've started, and maybe I can even help finish the implementation!
I pushed the branch rebind-debug https://github.com/Pasvaz/bindonce/blob/rebind-debug/bindonce.js , it works but it's still embrional, I need to test it extensively and to rewrite/clean the code.
It uses the directive refresh-on="message"
and one-watcher
to refresh the binders. Feel free to play with it but don't use it in production.
@rileylark it would be nice if you and the others could be test the rebind-debug branch extensively in order to evidentiate the bugs or memory leaks so I can change or confirm the way it works.
Thanks a bunch - I played with it some this weekend and will have some serious time this week.
Hah, I hadn't seen your last comment when I posted. Yes, I'll be happy to send you some of my tests. Is the new demo
folder a good place to put new uses?
I didn't have angular set up in the same build setup that you have, so in my initial test page I just included it from the CDN.
feel free to modify the demo as you want or to create new ones, that branch is supposed to be a work in progress so it is quite wild. At the moment, the first approach was to emulate angular and so to destruct and rebuild each bo-directive, the next step will be to improve it and reuse elements instead of removing them in order to speed up the whole process.
@Pasvaz I just sent you a PR with a simple demo for bo-src and bo-style.
I am not sure that $broadcast and $emit are going to be sufficient for my project. I am making a slide editor, with infrequently-changing slides. Each slide is represented twice: once in a long list of all of the previews, and again in the main editor area.
These are sibling scopes, and each of my slides should have its own rebind-on
event, so I think I would have to $emit the change up to $rootScope and then $broadcast them back down. Blegh!
I have an alternative idea to using the $scopes as event busses: a complementary bindonceNotify service that I can inject into any required code. My client code can call bindonceNotify('customUpdateEventName'), and your rebind-on api can register on a back end of the service. That way we can ignore the $scopes altogether, avoid muddying up the $on handlers, and have a kind of private channel for rebind notifications.
What do you think? I can submit another PR for this if you think it's a worthwhile direction to explore.
I went ahead and sketched it out in #60
Any further progress on rebind
? :)
I need this in an app I'm currently developing on :)
@archer96 I've made an Angular fork that does this, it is at:
https://github.com/r3m0t/angular.js/tree/digest_limit
It is built at:
https://github.com/r3m0t/bower-angular tag: 1.2.14-build.local+sha.1289c58
or v1.2.15-build.local+sha.9660989
An example is at:
https://gist.github.com/r3m0t/9271790
Watch out, it works very differently from pasvaz.bindonce. You can use ng-
for everything instead of bo-
, but inside the new-once
directive all the directives are affected.
guys I'll complete it asap, right now I'm busy dealing with some deadlines. @archer96 could you test the rebind branch, it's not complete but some feedback could surely help.
Hello,
I tried using that branch but there is one tiny "bug" that is annoying. Firstly my code:
<body ng-controller="MainCtrl">
<button ng-click="AddItem()">Add Item</button>
<button ng-click="RemoveFirstItem()">Remove First Item</button>
<ul>
<li ng-show="!items">Items are not loaded, yet!</li>
<li ng-show="items && !items.length">No items available!</li>
<li bindonce="items" refresh-on="'rinfresca'" ng-repeat="item in items">
<span bo-text="item.title"></span><br>
<span bo-text="item.description"></span>
</li>
</ul>
</body>
here my javsacript code:
var app = angular.module('bindoncedebug', ['pasvaz.bindonce']);
app.controller('MainCtrl', function ($scope, $q, $timeout) {
var count = 0;
$scope.AddItem = function () {
$scope.items.push({
title: 'Item ' + (++count),
description: 'this is item number ' + count
});
$scope.$broadcast('rinfresca');
};
$scope.RemoveFirstItem = function () {
$scope.items.shift();
$scope.$broadcast('rinfresca');
};
$timeout(function () {
$scope.items = [];
}, 1500)
$timeout(function () {
$scope.items = [
{
title: 'Item 1',
description: 'this is item number 1'
},
{
title: 'Item 2',
description: 'this is item number 2'
},
{
title: 'Item 3',
description: 'this is item number 3'
}
];
count = $scope.items.length;
}, 3000)
});
Rebind works well when putting refresh-on
and bindonce
on ul
but when putting it on li
it get following error when trying to remove an element:
TypeError: Object #<HTMLLIElement> has no method 'removeWatcher'
at HTMLLIElement.ctrl.destroy (file:///Users/__myName__/github/local/bindonce/bindonce.js:176:12)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:27:208
at r (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:7:386)
at Object.$c.c [as handle] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:27:190)
at cc (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:23:426)
at Da (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:23:57)
at r.remove (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:140:169)
at Object.R.(anonymous function) [as remove] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:141:414)
at Object.leave (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:143:309)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:187:25
I'd like to use refresh-on
on list elements as seen in this example.
Regards, Andre
I am getting the same error as Andre when using https://github.com/Pasvaz/bindonce/blob/rebind-debug/bindonce.js
TypeError: Object #
Pasvaz, any idea on when you think you will have some time to look into this issue?
Thanks,
Raj
@rajdeepg, please try it now
Hi Pasvaz,
I just tried the latest and no longer getting the 'removeWatcher' error but also not seeing my ng-repeat update it self.
Here is the code I am using: <div class="card selectable" data-ng-class="{ checked: storageItem.checked, last: storageItem.lastColumn}" data-bindonce="storageItems" data-refresh-on="'refreshStorageItemList'" data-ng-repeat="storageItem in storageItems" data-index="{{$index}}" data-file-name="{{storageItem.Name}}" data-mo-drag data-mo-drop="dropFiles(draggedItemIndex, droppedItemIndex)" data-ng-drag-multiple="{{ storageItem.checked }}" data-mo-hover data-mo-menu="getStandardActions" data-mo-menu-for="storageItem" data-mo-menu-on="contextmenu" data-mo-menu-title="{{ i18n.Actions }}">
In My controller: var index = $scope.storageItems.indexOf(items[0]); $scope.storageItems[index].Name = items[0].Name; $scope.$broadcast('refreshStorageItemList'); $scope.$apply();
I am updating the Name field in the item and hoping that it refreshes in my grid but it is not refreshing? Is there something I am doing wrong?
If you can share some sample code on how this should work that will be great?
Thanks,
Raj
+1 :) Following this interesting feature...
I'm using bo-text and bo-class, and can confirm refresh-on is working with 31148e7. Thanks, Pasvaz!
I am trying to force refresh my table but its not refreshing. Can anyone please help me on how to do this?
HTML code:
<tbody bindonce="filteredItems" refresh-on="refreshTaskList" ng-repeat="task in filteredItems | orderBy:sortingOrder:reverse">
<tr>
<td><span bo-bind="task.serviceTypeName | isEmpty : 'None'"></span></td>
<td ><span bo-bind="task.percentageCompleted | isEmpty : 'Not Started'"></span></td>
</tr>
</tbody>
Controller code: $scope.$broadcast('refreshTaskList');
Please help me...
Exciting feature! Any help needed besides testing?
Yeah, that would be excellent! It would actually allow me to transform every single group of watchers to just one watcher. Tell us what you need and maybe we'll help you ;)
Hi! Any idea when bo-refresh-on will be production ready?
Awesome. Just came across this issue/feature while looking into other things... Can't wait for production-ready!
@dominicglenn : Your code for line 188: scope.bindonceController = bindonceController;
seems to be wrong, scope is undefined. Can you verify it?
@fidoboy I wrote that code ages ago when the bindonce code was very different from what it is now; I think they have a different way to of doing this now. If you still want to do it why don't you try binder.scope
instead?
Any idea where this feature has gone recently? Thanks a lot.
:smile: i'm counting the days… bind once directive is really amazing and having the rebind feature… it could be perfect!! I hope that this could be available soon…
U know another way to sort of do this is to wrap your bindonce directive inside something else that will change, like a top-level object with infrequent watch triggers. When it does change, all the DOM children are refreshed, even if they are then "static" again after that.
+1
In the meantime - check out this: https://github.com/pcw216/angular-watch-when . Seems like to be a complete solution for that problem! Haven't got time yet to check that in a real app, but looks interesting.
+1
+1
+1
+1
+1
Take a look on this directive http://kent.doddsfamily.us/kcd-angular/#/kcd-recompile
Here is my interpretation of 'kcd-recompile' directive (it uses angular 1.3 and broadcast events) http://jsbin.com/pigofojogo/2/edit?html,js,output
Is this feature currently under development? or is it advised to try alternative like kdc-recompile? I tried this latter with Angular 1.3, can't manage to make it work when wrapping an ng-repeat... Thanks :)
+1 What happen to this? any idea when it will be available? Did anyone succeed with a workaround?
Well, I'll just recommend you switching to angular 1.3 and to plugins mentioned above, they work perfectly.
Is it possible to force refresh of bindonce item?