Comments (14)
@ashfurrow should we close this? bindTo()
should have taken care of this
from action.
Cool, thanks! And thanks again for adding it!
from action.
That's one of the reasons why I mostly use Action<SomeType, Void>
instead -- and that's perfectly fine! I view CocoaAction
as just a shortcut for the most common case but don't have an issue with using Action
when more flexibility is needed.
from action.
Submitted a pull request: #30
from action.
Could we use protocols to be sneaky here? Like:
typealias CocoaAction = Action<ActionInput, ActionOutput>
And then define those two protocols as empty and users can conform with their own types? Not sure. There's no easy answer, but I think it's an important discussion to have.
from action.
Hmm of course Swift 3 is going to come along in a little while and then we will have generic typealiases negating all of these workarounds. We could also consider a generic type wrapped in an enum/struct for now (the usual trick) until Swift 3? I'm not a huge fan of these but could work, eg:
struct GenericAction<Y, R> {
typealias T = CocoaAction<Y, R>
}
let action = GenericAction<Void, Observable<String>>.T()
from action.
The problem comes from the rx_action
property which, last time I tried, caused a compiler error in the UIButton
extension.
from action.
It may sound stupid but.. why a CocoaAction has to be an Action?
In ReactiveCocoa they've implemented it as a standalone NSObject that can be assigned to UIControls (or its macOS equivalent, I'm not a Mac expert at all).
Basically it ties itself up to an existing Action and just provides a custom input parameter defined inside a closure whenever there's interaction with the control
I think it should be better to avoid useless creation of Actions (they involve too many observables in the process, it can be performance killer sometimes) if we only need a different input to perform the same thing.
from action.
I've tried to implement it (heavily "inspired" by RAC's CocoaAction) here
I've named it "ControlAction" so that it doesn't break current behaviour
The main drawback is that we're losing "Sender" type inside the closure, honestly I've never used it anyway.
from action.
Ah interesting, so it acts as like a wrapper for Action
then? Neat idea. Anyone have feedback on this? Would love to discuss on a pull request.
from action.
I'm not sure that introducing Action wrapper is a right way for RxCocoa users.
I think our Action do not necessarily have to be the same as RAC's Action, because API design of each libraries differ from each other. RAC assumes that all actions triggered by Cocoa components is expressed as CocoaAction, but RxCocoa doesn't.
Additionally, we already have a mechanism that just provides a custom input parameter on Action.
inputs
subject can receive flexible inputs like below:
let button = UIButton()
let barButtonItem = UIBarButtonItem()
let disposeBag = DisposeBag()
let action = Action<String, Void> { input in
print("\(input) is pressed.")
}
button.rx.tap
.map { _ in "UIButton" }
.bindTo(action.input)
.addDisposableTo(disposeBag)
barButtonItem.rx.tap
.map { _ in "UIBarButtonItem" }
.bindTo(action.input)
.addDisposableTo(disposeBag)
Now, we have 2 choices to give a custom input parameters on Action:
- Use existing RxCocoa API and connect it to inputs subject.
- Add an action property to Cocoa components and set CocoaAction there.
Personally, I think 1 is more reasonable than 2.
from action.
@ishkawa this is really interesting, the main problem I see is that, in this way, the button's enabled property is not in sync with the action executing state.
I don't think either it's absolutely necessary to "mirror" RAC behavior, (otherwise I'd continue to use that instead of Rx.). It's not perfect at all, it's difficult to explain to new developers and has some "complications" that I don't need.
But, on the other hand, I don't see any downside to simply add a second "rx_action2" (I've called controlAction
in my fork) that automatically many controls with a single action, with input customizations. It would not break (I think) any of the existing behaviors.
Let me also clarify why I came to this kind of conclusion.
Usually, when I do MVVM on iOS, I prefer to keep a single Action for each viewController's viewModel. In this way I can keep error and "showLoader" handling in one single place, and I don't have to replicate binding code for each action that could lead to an error (or could show a progress bar for long time operations). What really discriminates what the Action should do is the Input I provide to it. And the input depends on which button is pressed.
In this way, I have no business logic at all in the VC, i just have to tell the ViewModel to execute the Action with a converted input (usually an enum with all the possible choices in a viewModel). That's why I needed something different from your typealiased CocoaAction.
Maybe I can work out something on your suggestions that doesn't involve the creation of a new class, I'll let you know. In the meanwhile, THANKS :)
from action.
Let's keep it open until we add documentation to the readme?
from action.
ok, I'm trying to do it right now BTW
from action.
Related Issues (20)
- Use of undeclared type 'InputSubject' HOT 1
- Potential Memory Leak HOT 2
- Version 4.0.1 could not be found HOT 1
- Memory leak caused by `bind(to:inputTransform:)` HOT 1
- Problem installing with CocoaPods
- Support RxSwift 5.1.0 HOT 1
- Action.elements does not emit item for a inflight request HOT 1
- Crash when using Carthage-cache and Rx v5.1.1 HOT 3
- Pod version not updated HOT 2
- Fix CI HOT 2
- Building for iOS, but the linked framework 'RxCocoa.framework' was built for macOS. (in target 'Action' from project 'Action') HOT 5
- Combine support
- Retain cycle in bind(to:input:) HOT 5
- RxSwift v6.0.0 question HOT 1
- Retain Cycle CocoaAction HOT 2
- alertController 结合 Alamofire会报错
- UIRefreshControl being displayed before view appears
- Ambiguous use of 'init(enabledIf:workFactory:)'
- auto-release Action in function scope
- v4.2.0 throw error when building code
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from action.