replaceMoleculeBehavior, cleaner child replacement helper, first working sample.
This commit is contained in:
parent
022319c186
commit
1f895ebdbd
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
open class ListLeftVariableRadioButtonBodyTextModel: ListItemModel, MoleculeModelProtocol {
|
open class ListLeftVariableRadioButtonBodyTextModel: ListItemModel, ParentMoleculeModelProtocol {
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
@ -15,7 +15,16 @@ open class ListLeftVariableRadioButtonBodyTextModel: ListItemModel, MoleculeMode
|
|||||||
public static var identifier: String = "listLVRBBdy"
|
public static var identifier: String = "listLVRBBdy"
|
||||||
public var radioButton: RadioButtonModel
|
public var radioButton: RadioButtonModel
|
||||||
public var headlineBody: HeadlineBodyModel
|
public var headlineBody: HeadlineBodyModel
|
||||||
|
|
||||||
|
public var children: [MoleculeModelProtocol] {
|
||||||
|
[radioButton, headlineBody]
|
||||||
|
}
|
||||||
|
|
||||||
|
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool {
|
||||||
|
return replace(childMolecule: &radioButton, with: replacementMolecule)
|
||||||
|
|| replace(childMolecule: &headlineBody, with: replacementMolecule)
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|||||||
@ -25,12 +25,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool {
|
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool {
|
||||||
return [
|
return replace(childMolecule:&headline, with: replacementMolecule)
|
||||||
\HeadlineBodyModel.headline,
|
|| replace(childMolecule:&body, with: replacementMolecule)
|
||||||
\HeadlineBodyModel.body,
|
|
||||||
].contains {
|
|
||||||
replaceChildMolecule(on: self, keyPath: $0, replacementMolecule: replacementMolecule)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -26,6 +26,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool {
|
public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool {
|
||||||
|
// IDEALLY:
|
||||||
|
//return replace(inChildMolecules: &molecules, with: replacementMolecule)
|
||||||
|
|
||||||
guard let replacementMolecule = replacementMolecule as? StackItemModelProtocol & MoleculeModelProtocol else { return false }
|
guard let replacementMolecule = replacementMolecule as? StackItemModelProtocol & MoleculeModelProtocol else { return false }
|
||||||
guard let matchingIndex = molecules.firstIndex(where: { molecule in
|
guard let matchingIndex = molecules.firstIndex(where: { molecule in
|
||||||
molecule.id == replacementMolecule.id
|
molecule.id == replacementMolecule.id
|
||||||
|
|||||||
@ -60,20 +60,29 @@ public extension ParentMoleculeModelProtocol {
|
|||||||
/// Top level test to replace child molecules. Each parent molecule should attempt to replace.
|
/// Top level test to replace child molecules. Each parent molecule should attempt to replace.
|
||||||
func replaceChildMolecule(with molecule: MoleculeModelProtocol) -> Bool { return false }
|
func replaceChildMolecule(with molecule: MoleculeModelProtocol) -> Bool { return false }
|
||||||
|
|
||||||
/// Helper function for replacing molecules on a path.
|
/// Helper function for replacing molecules.
|
||||||
func replaceChildMolecule<P: ParentMoleculeModelProtocol, T: MoleculeModelProtocol>(on target: P, keyPath: ReferenceWritableKeyPath<P, T?>, replacementMolecule: MoleculeModelProtocol) -> Bool {
|
func replace<T: MoleculeModelProtocol>(childMolecule: inout T?, with replacementMolecule: MoleculeModelProtocol) -> Bool {
|
||||||
if let currentMolecule = target[keyPath: keyPath], currentMolecule.id == replacementMolecule.id, let newHeadline = replacementMolecule as? T {
|
if childMolecule != nil, childMolecule?.id == replacementMolecule.id, let newHeadline = replacementMolecule as? T {
|
||||||
target[keyPath: keyPath] = newHeadline
|
childMolecule = newHeadline
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceChildMolecule<P: ParentMoleculeModelProtocol, T: MoleculeModelProtocol>(on target: P, keyPath: ReferenceWritableKeyPath<P, T>, replacementMolecule: MoleculeModelProtocol) -> Bool {
|
func replace<T: MoleculeModelProtocol>(childMolecule: inout T, with replacementMolecule: MoleculeModelProtocol) -> Bool {
|
||||||
if target[keyPath: keyPath].id == replacementMolecule.id, let newHeadline = replacementMolecule as? T {
|
if childMolecule.id == replacementMolecule.id, let newHeadline = replacementMolecule as? T {
|
||||||
target[keyPath: keyPath] = newHeadline
|
childMolecule = newHeadline
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func replace<T>(inChildMolecules molecules: inout [T], with replacementMolecule: MoleculeModelProtocol) -> Bool where T: MoleculeModelProtocol {
|
||||||
|
guard let replacementMolecule = replacementMolecule as? T else { return false }
|
||||||
|
guard let matchingIndex = molecules.firstIndex(where: { molecule in
|
||||||
|
molecule.id == replacementMolecule.id
|
||||||
|
}) else { return false }
|
||||||
|
molecules[matchingIndex] = replacementMolecule
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,10 +51,13 @@ public extension MoleculeTreeTraversalProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) {
|
func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool {
|
||||||
|
var didReplaceMolecule = false
|
||||||
depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in
|
depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in
|
||||||
guard let parentMolecule = molecule as? ParentMoleculeModelProtocol else { return }
|
guard let parentMolecule = molecule as? ParentMoleculeModelProtocol else { return }
|
||||||
stop = parentMolecule.replaceChildMolecule(with: replacementMolecule)
|
didReplaceMolecule = parentMolecule.replaceChildMolecule(with: replacementMolecule)
|
||||||
|
stop = didReplaceMolecule
|
||||||
}
|
}
|
||||||
|
return didReplaceMolecule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,7 +74,9 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
open func modulesToListenFor() -> [String]? {
|
open func modulesToListenFor() -> [String]? {
|
||||||
loadObject?.requestParameters?.allModules()
|
let requestModules = loadObject?.requestParameters?.allModules() ?? []
|
||||||
|
let behaviorModules = behaviors?.flatMap { $0.modulesToListenFor() } ?? []
|
||||||
|
return requestModules + behaviorModules
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc open func responseJSONUpdated(notification: Notification) {
|
@objc open func responseJSONUpdated(notification: Notification) {
|
||||||
|
|||||||
@ -14,12 +14,15 @@ public protocol PageBehaviorProtocol: ModelHandlerProtocol {
|
|||||||
/// Should the behavior persist regardless of page behavior model updates.
|
/// Should the behavior persist regardless of page behavior model updates.
|
||||||
var transcendsPageUpdates: Bool { get }
|
var transcendsPageUpdates: Bool { get }
|
||||||
|
|
||||||
|
func modulesToListenFor() -> [String]
|
||||||
|
|
||||||
/// Initializes the behavior with the model
|
/// Initializes the behavior with the model
|
||||||
init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?)
|
init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?)
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension PageBehaviorProtocol {
|
public extension PageBehaviorProtocol {
|
||||||
var transcendsPageUpdates: Bool { return false }
|
var transcendsPageUpdates: Bool { return false }
|
||||||
|
func modulesToListenFor() -> [String] { return [] }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +49,6 @@ public extension PageMoleculeTransformationBehavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
||||||
|
|
||||||
func willShowPage(_ delegateObject: MVMCoreUIDelegateObject?)
|
func willShowPage(_ delegateObject: MVMCoreUIDelegateObject?)
|
||||||
func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?)
|
func onPageShown(_ delegateObject: MVMCoreUIDelegateObject?)
|
||||||
func willHidePage(_ delegateObject: MVMCoreUIDelegateObject?)
|
func willHidePage(_ delegateObject: MVMCoreUIDelegateObject?)
|
||||||
|
|||||||
39
MVMCoreUI/Behaviors/ReplacementMoleculeBehavior.swift
Normal file
39
MVMCoreUI/Behaviors/ReplacementMoleculeBehavior.swift
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// ReplacementMoleculeBehavior.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kyle Hedden on 9/12/23.
|
||||||
|
// Copyright © 2023 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MVMCore
|
||||||
|
|
||||||
|
public class ReplacableMoleculeBehaviorModel: PageBehaviorModelProtocol {
|
||||||
|
public class var identifier: String { "replaceMoleculeBehavior" }
|
||||||
|
public var shouldAllowMultipleInstances: Bool { true }
|
||||||
|
public var moleculeIds: [String]
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ReplacableMoleculeBehavior: PageMoleculeTransformationBehavior {
|
||||||
|
var moleculeIds: [String]
|
||||||
|
|
||||||
|
public required init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
|
moleculeIds = (model as! ReplacableMoleculeBehaviorModel).moleculeIds
|
||||||
|
}
|
||||||
|
|
||||||
|
public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
|
var shouldRefreshUI = false
|
||||||
|
for moleculeId in moleculeIds {
|
||||||
|
guard let replacementModel = delegateObject?.moleculeDelegate?.getModuleWithName(moleculeId) else { continue }
|
||||||
|
let didReplace = rootMolecules.contains(where: { model in
|
||||||
|
return model.replaceMolecule(with: replacementModel)
|
||||||
|
})
|
||||||
|
shouldRefreshUI = shouldRefreshUI || didReplace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func modulesToListenFor() -> [String] {
|
||||||
|
moleculeIds
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -227,6 +227,7 @@ open class CoreUIModelMapping: ModelMapping {
|
|||||||
ModelRegistry.register(handler: PageGetContactBehavior.self, for: PageGetContactBehaviorModel.self)
|
ModelRegistry.register(handler: PageGetContactBehavior.self, for: PageGetContactBehaviorModel.self)
|
||||||
ModelRegistry.register(handler: AddRemoveMoleculesBehavior.self, for: AddRemoveMoleculesBehaviorModel.self)
|
ModelRegistry.register(handler: AddRemoveMoleculesBehavior.self, for: AddRemoveMoleculesBehaviorModel.self)
|
||||||
ModelRegistry.register(handler: GetNotificationAuthStatusBehavior.self, for: GetNotificationAuthStatusBehaviorModel.self)
|
ModelRegistry.register(handler: GetNotificationAuthStatusBehavior.self, for: GetNotificationAuthStatusBehaviorModel.self)
|
||||||
|
ModelRegistry.register(handler: ReplacableMoleculeBehavior.self, for: ReplacableMoleculeBehaviorModel.self)
|
||||||
}
|
}
|
||||||
|
|
||||||
open override class func registerActions() {
|
open override class func registerActions() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user